toolkit/crashreporter/google-breakpad/src/processor/disassembler_x86_unittest.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // All rights reserved.
     2 //
     3 // Redistribution and use in source and binary forms, with or without
     4 // modification, are permitted provided that the following conditions are
     5 // met:
     6 //
     7 //     * Redistributions of source code must retain the above copyright
     8 // notice, this list of conditions and the following disclaimer.
     9 //     * Redistributions in binary form must reproduce the above
    10 // copyright notice, this list of conditions and the following disclaimer
    11 // in the documentation and/or other materials provided with the
    12 // distribution.
    13 //     * Neither the name of Google Inc. nor the names of its
    14 // contributors may be used to endorse or promote products derived from
    15 // this software without specific prior written permission.
    16 //
    17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE//
    28 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    29 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    30 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    31 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    32 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    33 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    34 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    35 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    36 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    37 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    38 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    40 #include <unistd.h>
    42 #include "breakpad_googletest_includes.h"
    43 #include "processor/disassembler_x86.h"
    44 #include "third_party/libdisasm/libdis.h"
    46 namespace {
    48 using google_breakpad::DisassemblerX86;
    50 unsigned char just_return[] = "\xc3";  // retn
    52 unsigned char invalid_instruction[] = "\x00";  // invalid
    54 unsigned char read_eax_jmp_eax[] =
    55     "\x8b\x18"                  // mov ebx, [eax];
    56     "\x33\xc9"                  // xor ebx, ebx;
    57     "\xff\x20"                  // jmp eax;
    58     "\xc3";                     // retn;
    60 unsigned char write_eax_arg_to_call[] =
    61     "\x89\xa8\x00\x02\x00\x00"  // mov [eax+200], ebp;
    62     "\xc1\xeb\x02"              // shr ebx, 2;
    63     "\x50"                      // push eax;
    64     "\xe8\xd1\x24\x77\x88"      // call something;
    65     "\xc3";                     // retn;
    67 unsigned char read_edi_stosb[] =
    68     "\x8b\x07"                  // mov eax, [edi];
    69     "\x8b\xc8"                  // mov ecx, eax;
    70     "\xf3\xaa"                  // rep stosb;
    71     "\xc3";                     // retn;
    73 unsigned char read_clobber_write[] =
    74     "\x03\x18"                  // add ebx, [eax];
    75     "\x8b\xc1"                  // mov eax, ecx;
    76     "\x89\x10"                  // mov [eax], edx;
    77     "\xc3";                     // retn;
    79 unsigned char read_xchg_write[] =
    80     "\x03\x18"                  // add ebx, [eax];
    81     "\x91"                      // xchg eax, ecx;
    82     "\x89\x18"                  // mov [eax], ebx;
    83     "\x89\x11"                  // mov [ecx], edx;
    84     "\xc3";                     // retn;
    86 unsigned char read_cmp[] =
    87     "\x03\x18"                  // add ebx, [eax];
    88     "\x83\xf8\x00"              // cmp eax, 0;
    89     "\x74\x04"                  // je +4;
    90     "\xc3";                     // retn;
    92 TEST(DisassemblerX86Test, SimpleReturnInstruction) {
    93   DisassemblerX86 dis(just_return, sizeof(just_return)-1, 0);
    94   EXPECT_EQ(1U, dis.NextInstruction());
    95   EXPECT_TRUE(dis.currentInstructionValid());
    96   EXPECT_EQ(0U, dis.flags());
    97   EXPECT_TRUE(dis.endOfBlock());
    98   EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup());
    99   const libdis::x86_insn_t* instruction = dis.currentInstruction();
   100   EXPECT_EQ(libdis::insn_controlflow, instruction->group);
   101   EXPECT_EQ(libdis::insn_return, instruction->type);
   102   EXPECT_EQ(0U, dis.NextInstruction());
   103   EXPECT_FALSE(dis.currentInstructionValid());
   104   EXPECT_EQ(NULL, dis.currentInstruction());
   105 }
   107 TEST(DisassemblerX86Test, SimpleInvalidInstruction) {
   108   DisassemblerX86 dis(invalid_instruction, sizeof(invalid_instruction)-1, 0);
   109   EXPECT_EQ(0U, dis.NextInstruction());
   110   EXPECT_FALSE(dis.currentInstructionValid());
   111 }
   113 TEST(DisassemblerX86Test, BadReadLeadsToBranch) {
   114   DisassemblerX86 dis(read_eax_jmp_eax, sizeof(read_eax_jmp_eax)-1, 0);
   115   EXPECT_EQ(2U, dis.NextInstruction());
   116   EXPECT_TRUE(dis.currentInstructionValid());
   117   EXPECT_EQ(0U, dis.flags());
   118   EXPECT_FALSE(dis.endOfBlock());
   119   EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup());
   120   EXPECT_TRUE(dis.setBadRead());
   121   EXPECT_EQ(2U, dis.NextInstruction());
   122   EXPECT_TRUE(dis.currentInstructionValid());
   123   EXPECT_EQ(0U, dis.flags());
   124   EXPECT_FALSE(dis.endOfBlock());
   125   EXPECT_EQ(libdis::insn_logic, dis.currentInstructionGroup());
   126   EXPECT_EQ(2U, dis.NextInstruction());
   127   EXPECT_TRUE(dis.currentInstructionValid());
   128   EXPECT_EQ(google_breakpad::DISX86_BAD_BRANCH_TARGET, dis.flags());
   129   EXPECT_FALSE(dis.endOfBlock());
   130   EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup());
   131 }
   133 TEST(DisassemblerX86Test, BadWriteLeadsToPushedArg) {
   134   DisassemblerX86 dis(write_eax_arg_to_call,
   135                       sizeof(write_eax_arg_to_call)-1, 0);
   136   EXPECT_EQ(6U, dis.NextInstruction());
   137   EXPECT_TRUE(dis.currentInstructionValid());
   138   EXPECT_EQ(0U, dis.flags());
   139   EXPECT_FALSE(dis.endOfBlock());
   140   EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup());
   141   EXPECT_TRUE(dis.setBadWrite());
   142   EXPECT_EQ(3U, dis.NextInstruction());
   143   EXPECT_TRUE(dis.currentInstructionValid());
   144   EXPECT_EQ(0U, dis.flags());
   145   EXPECT_FALSE(dis.endOfBlock());
   146   EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup());
   147   EXPECT_EQ(1U, dis.NextInstruction());
   148   EXPECT_TRUE(dis.currentInstructionValid());
   149   EXPECT_EQ(0U, dis.flags());
   150   EXPECT_FALSE(dis.endOfBlock());
   151   EXPECT_EQ(5U, dis.NextInstruction());
   152   EXPECT_TRUE(dis.currentInstructionValid());
   153   EXPECT_EQ(google_breakpad::DISX86_BAD_ARGUMENT_PASSED, dis.flags());
   154   EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup());
   155   EXPECT_FALSE(dis.endOfBlock());
   156 }
   159 TEST(DisassemblerX86Test, BadReadLeadsToBlockWrite) {
   160   DisassemblerX86 dis(read_edi_stosb, sizeof(read_edi_stosb)-1, 0);
   161   EXPECT_EQ(2U, dis.NextInstruction());
   162   EXPECT_TRUE(dis.currentInstructionValid());
   163   EXPECT_EQ(0U, dis.flags());
   164   EXPECT_FALSE(dis.endOfBlock());
   165   EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup());
   166   EXPECT_TRUE(dis.setBadRead());
   167   EXPECT_EQ(2U, dis.NextInstruction());
   168   EXPECT_TRUE(dis.currentInstructionValid());
   169   EXPECT_EQ(0U, dis.flags());
   170   EXPECT_FALSE(dis.endOfBlock());
   171   EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup());
   172   EXPECT_EQ(2U, dis.NextInstruction());
   173   EXPECT_TRUE(dis.currentInstructionValid());
   174   EXPECT_EQ(google_breakpad::DISX86_BAD_BLOCK_WRITE, dis.flags());
   175   EXPECT_FALSE(dis.endOfBlock());
   176   EXPECT_EQ(libdis::insn_string, dis.currentInstructionGroup());
   177 }
   179 TEST(DisassemblerX86Test, BadReadClobberThenWrite) {
   180   DisassemblerX86 dis(read_clobber_write, sizeof(read_clobber_write)-1, 0);
   181   EXPECT_EQ(2U, dis.NextInstruction());
   182   EXPECT_TRUE(dis.currentInstructionValid());
   183   EXPECT_EQ(0U, dis.flags());
   184   EXPECT_FALSE(dis.endOfBlock());
   185   EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup());
   186   EXPECT_TRUE(dis.setBadRead());
   187   EXPECT_EQ(2U, dis.NextInstruction());
   188   EXPECT_TRUE(dis.currentInstructionValid());
   189   EXPECT_EQ(0U, dis.flags());
   190   EXPECT_FALSE(dis.endOfBlock());
   191   EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup());
   192   EXPECT_EQ(2U, dis.NextInstruction());
   193   EXPECT_TRUE(dis.currentInstructionValid());
   194   EXPECT_EQ(0U, dis.flags());
   195   EXPECT_FALSE(dis.endOfBlock());
   196   EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup());
   197 }
   199 TEST(DisassemblerX86Test, BadReadXCHGThenWrite) {
   200   DisassemblerX86 dis(read_xchg_write, sizeof(read_xchg_write)-1, 0);
   201   EXPECT_EQ(2U, dis.NextInstruction());
   202   EXPECT_TRUE(dis.currentInstructionValid());
   203   EXPECT_EQ(0U, dis.flags());
   204   EXPECT_FALSE(dis.endOfBlock());
   205   EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup());
   206   EXPECT_TRUE(dis.setBadRead());
   207   EXPECT_EQ(1U, dis.NextInstruction());
   208   EXPECT_TRUE(dis.currentInstructionValid());
   209   EXPECT_EQ(0U, dis.flags());
   210   EXPECT_FALSE(dis.endOfBlock());
   211   EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup());
   212   EXPECT_EQ(2U, dis.NextInstruction());
   213   EXPECT_TRUE(dis.currentInstructionValid());
   214   EXPECT_EQ(0U, dis.flags());
   215   EXPECT_FALSE(dis.endOfBlock());
   216   EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup());
   217   EXPECT_EQ(2U, dis.NextInstruction());
   218   EXPECT_TRUE(dis.currentInstructionValid());
   219   EXPECT_EQ(google_breakpad::DISX86_BAD_WRITE, dis.flags());
   220   EXPECT_FALSE(dis.endOfBlock());
   221   EXPECT_EQ(libdis::insn_move, dis.currentInstructionGroup());
   222 }
   224 TEST(DisassemblerX86Test, BadReadThenCMP) {
   225   DisassemblerX86 dis(read_cmp, sizeof(read_cmp)-1, 0);
   226   EXPECT_EQ(2U, dis.NextInstruction());
   227   EXPECT_TRUE(dis.currentInstructionValid());
   228   EXPECT_EQ(0U, dis.flags());
   229   EXPECT_FALSE(dis.endOfBlock());
   230   EXPECT_EQ(libdis::insn_arithmetic, dis.currentInstructionGroup());
   231   EXPECT_TRUE(dis.setBadRead());
   232   EXPECT_EQ(3U, dis.NextInstruction());
   233   EXPECT_TRUE(dis.currentInstructionValid());
   234   EXPECT_EQ(google_breakpad::DISX86_BAD_COMPARISON, dis.flags());
   235   EXPECT_FALSE(dis.endOfBlock());
   236   EXPECT_EQ(libdis::insn_comparison, dis.currentInstructionGroup());
   237   EXPECT_EQ(2U, dis.NextInstruction());
   238   EXPECT_TRUE(dis.currentInstructionValid());
   239   EXPECT_EQ(google_breakpad::DISX86_BAD_COMPARISON, dis.flags());
   240   EXPECT_FALSE(dis.endOfBlock());
   241   EXPECT_EQ(libdis::insn_controlflow, dis.currentInstructionGroup());
   242 }
   243 }

mercurial