189c3c8c4SVlad Tsyrklevich //===- llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp --------------===//
289c3c8c4SVlad Tsyrklevich //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
689c3c8c4SVlad Tsyrklevich //
789c3c8c4SVlad Tsyrklevich //===----------------------------------------------------------------------===//
889c3c8c4SVlad Tsyrklevich
989c3c8c4SVlad Tsyrklevich #include "../tools/llvm-cfi-verify/lib/FileAnalysis.h"
105ff01cdcSMitch Phillips #include "../tools/llvm-cfi-verify/lib/GraphBuilder.h"
1189c3c8c4SVlad Tsyrklevich #include "gmock/gmock.h"
1289c3c8c4SVlad Tsyrklevich #include "gtest/gtest.h"
1389c3c8c4SVlad Tsyrklevich
1489c3c8c4SVlad Tsyrklevich #include "llvm/BinaryFormat/ELF.h"
15db29f437Sserge-sans-paille #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
1689c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCAsmInfo.h"
1789c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCContext.h"
1889c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCDisassembler/MCDisassembler.h"
1989c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCInst.h"
2089c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCInstPrinter.h"
2189c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCInstrAnalysis.h"
2289c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCInstrDesc.h"
2389c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCInstrInfo.h"
2489c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCObjectFileInfo.h"
2589c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCRegisterInfo.h"
2689c3c8c4SVlad Tsyrklevich #include "llvm/MC/MCSubtargetInfo.h"
2789b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
2889c3c8c4SVlad Tsyrklevich #include "llvm/Object/Binary.h"
2989c3c8c4SVlad Tsyrklevich #include "llvm/Object/COFF.h"
3089c3c8c4SVlad Tsyrklevich #include "llvm/Object/ELFObjectFile.h"
3189c3c8c4SVlad Tsyrklevich #include "llvm/Object/ObjectFile.h"
3289c3c8c4SVlad Tsyrklevich #include "llvm/Support/Casting.h"
3389c3c8c4SVlad Tsyrklevich #include "llvm/Support/CommandLine.h"
3489c3c8c4SVlad Tsyrklevich #include "llvm/Support/Error.h"
3589c3c8c4SVlad Tsyrklevich #include "llvm/Support/MemoryBuffer.h"
3689c3c8c4SVlad Tsyrklevich #include "llvm/Support/TargetSelect.h"
3789c3c8c4SVlad Tsyrklevich #include "llvm/Support/raw_ostream.h"
3889c3c8c4SVlad Tsyrklevich
3989c3c8c4SVlad Tsyrklevich #include <cstdlib>
4089c3c8c4SVlad Tsyrklevich
4189c3c8c4SVlad Tsyrklevich using Instr = ::llvm::cfi_verify::FileAnalysis::Instr;
4289c3c8c4SVlad Tsyrklevich using ::testing::Eq;
430ee26324SVlad Tsyrklevich using ::testing::Field;
4489c3c8c4SVlad Tsyrklevich
4589c3c8c4SVlad Tsyrklevich namespace llvm {
4689c3c8c4SVlad Tsyrklevich namespace cfi_verify {
4789c3c8c4SVlad Tsyrklevich namespace {
4806e7e579SJoel Galenson class ELFTestFileAnalysis : public FileAnalysis {
4989c3c8c4SVlad Tsyrklevich public:
ELFTestFileAnalysis(StringRef Trip)5006e7e579SJoel Galenson ELFTestFileAnalysis(StringRef Trip)
5106e7e579SJoel Galenson : FileAnalysis(Triple(Trip), SubtargetFeatures()) {}
5289c3c8c4SVlad Tsyrklevich
5389c3c8c4SVlad Tsyrklevich // Expose this method publicly for testing.
parseSectionContents(ArrayRef<uint8_t> SectionBytes,object::SectionedAddress Address)5489c3c8c4SVlad Tsyrklevich void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
5577fc1f60SAlexey Lapshin object::SectionedAddress Address) {
5677fc1f60SAlexey Lapshin FileAnalysis::parseSectionContents(SectionBytes, Address);
5789c3c8c4SVlad Tsyrklevich }
5889c3c8c4SVlad Tsyrklevich
initialiseDisassemblyMembers()5989c3c8c4SVlad Tsyrklevich Error initialiseDisassemblyMembers() {
6089c3c8c4SVlad Tsyrklevich return FileAnalysis::initialiseDisassemblyMembers();
6189c3c8c4SVlad Tsyrklevich }
6289c3c8c4SVlad Tsyrklevich };
6389c3c8c4SVlad Tsyrklevich
6489c3c8c4SVlad Tsyrklevich class BasicFileAnalysisTest : public ::testing::Test {
6506e7e579SJoel Galenson public:
BasicFileAnalysisTest(StringRef Trip)6649406fa9SSimon Pilgrim BasicFileAnalysisTest(StringRef Trip)
6749406fa9SSimon Pilgrim : SuccessfullyInitialised(false), Analysis(Trip) {}
6889c3c8c4SVlad Tsyrklevich protected:
SetUp()6931eb8349SLogan Smith void SetUp() override {
70c15bdf55SMitch Phillips IgnoreDWARFFlag = true;
71d9af383dSMitch Phillips SuccessfullyInitialised = true;
72d9af383dSMitch Phillips if (auto Err = Analysis.initialiseDisassemblyMembers()) {
73d9af383dSMitch Phillips handleAllErrors(std::move(Err), [&](const UnsupportedDisassembly &E) {
74d9af383dSMitch Phillips SuccessfullyInitialised = false;
75d9af383dSMitch Phillips outs()
7606e7e579SJoel Galenson << "Note: CFIVerifyTests are disabled due to lack of support "
77d9af383dSMitch Phillips "on this build.\n";
78d9af383dSMitch Phillips });
7989c3c8c4SVlad Tsyrklevich }
8089c3c8c4SVlad Tsyrklevich }
8189c3c8c4SVlad Tsyrklevich
82d9af383dSMitch Phillips bool SuccessfullyInitialised;
8306e7e579SJoel Galenson ELFTestFileAnalysis Analysis;
8489c3c8c4SVlad Tsyrklevich };
8589c3c8c4SVlad Tsyrklevich
8606e7e579SJoel Galenson class BasicX86FileAnalysisTest : public BasicFileAnalysisTest {
8706e7e579SJoel Galenson public:
BasicX86FileAnalysisTest()8806e7e579SJoel Galenson BasicX86FileAnalysisTest() : BasicFileAnalysisTest("x86_64--") {}
8906e7e579SJoel Galenson };
9006e7e579SJoel Galenson
9106e7e579SJoel Galenson class BasicAArch64FileAnalysisTest : public BasicFileAnalysisTest {
9206e7e579SJoel Galenson public:
BasicAArch64FileAnalysisTest()9306e7e579SJoel Galenson BasicAArch64FileAnalysisTest() : BasicFileAnalysisTest("aarch64--") {}
9406e7e579SJoel Galenson };
9506e7e579SJoel Galenson
TEST_F(BasicX86FileAnalysisTest,BasicDisassemblyTraversalTest)9606e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, BasicDisassemblyTraversalTest) {
97d9af383dSMitch Phillips if (!SuccessfullyInitialised)
987fc87159SPaul Robinson GTEST_SKIP();
9989c3c8c4SVlad Tsyrklevich Analysis.parseSectionContents(
10089c3c8c4SVlad Tsyrklevich {
10189c3c8c4SVlad Tsyrklevich 0x90, // 0: nop
10289c3c8c4SVlad Tsyrklevich 0xb0, 0x00, // 1: mov $0x0, %al
10389c3c8c4SVlad Tsyrklevich 0x48, 0x89, 0xe5, // 3: mov %rsp, %rbp
10489c3c8c4SVlad Tsyrklevich 0x48, 0x83, 0xec, 0x18, // 6: sub $0x18, %rsp
10589c3c8c4SVlad Tsyrklevich 0x48, 0xbe, 0xc4, 0x07, 0x40,
10689c3c8c4SVlad Tsyrklevich 0x00, 0x00, 0x00, 0x00, 0x00, // 10: movabs $0x4007c4, %rsi
10789c3c8c4SVlad Tsyrklevich 0x2f, // 20: (bad)
10889c3c8c4SVlad Tsyrklevich 0x41, 0x0e, // 21: rex.B (bad)
10989c3c8c4SVlad Tsyrklevich 0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
11089c3c8c4SVlad Tsyrklevich },
11177fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
11289c3c8c4SVlad Tsyrklevich
11389c3c8c4SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getInstruction(0x0));
11489c3c8c4SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getInstruction(0x1000));
11589c3c8c4SVlad Tsyrklevich
11689c3c8c4SVlad Tsyrklevich // 0xDEADBEEF: nop
11789c3c8c4SVlad Tsyrklevich const auto *InstrMeta = Analysis.getInstruction(0xDEADBEEF);
11889c3c8c4SVlad Tsyrklevich EXPECT_NE(nullptr, InstrMeta);
11989c3c8c4SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF, InstrMeta->VMAddress);
12089c3c8c4SVlad Tsyrklevich EXPECT_EQ(1u, InstrMeta->InstructionSize);
12189c3c8c4SVlad Tsyrklevich EXPECT_TRUE(InstrMeta->Valid);
12289c3c8c4SVlad Tsyrklevich
12389c3c8c4SVlad Tsyrklevich const auto *NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);
12489c3c8c4SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta));
12589c3c8c4SVlad Tsyrklevich const auto *PrevInstrMeta = InstrMeta;
12689c3c8c4SVlad Tsyrklevich
12789c3c8c4SVlad Tsyrklevich // 0xDEADBEEF + 1: mov $0x0, %al
12889c3c8c4SVlad Tsyrklevich InstrMeta = Analysis.getInstruction(0xDEADBEEF + 1);
12989c3c8c4SVlad Tsyrklevich EXPECT_NE(nullptr, InstrMeta);
13089c3c8c4SVlad Tsyrklevich EXPECT_EQ(NextInstrMeta, InstrMeta);
13189c3c8c4SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 1, InstrMeta->VMAddress);
13289c3c8c4SVlad Tsyrklevich EXPECT_EQ(2u, InstrMeta->InstructionSize);
13389c3c8c4SVlad Tsyrklevich EXPECT_TRUE(InstrMeta->Valid);
13489c3c8c4SVlad Tsyrklevich
13589c3c8c4SVlad Tsyrklevich NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);
13689c3c8c4SVlad Tsyrklevich EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));
13789c3c8c4SVlad Tsyrklevich PrevInstrMeta = InstrMeta;
13889c3c8c4SVlad Tsyrklevich
13989c3c8c4SVlad Tsyrklevich // 0xDEADBEEF + 3: mov %rsp, %rbp
14089c3c8c4SVlad Tsyrklevich InstrMeta = Analysis.getInstruction(0xDEADBEEF + 3);
14189c3c8c4SVlad Tsyrklevich EXPECT_NE(nullptr, InstrMeta);
14289c3c8c4SVlad Tsyrklevich EXPECT_EQ(NextInstrMeta, InstrMeta);
14389c3c8c4SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 3, InstrMeta->VMAddress);
14489c3c8c4SVlad Tsyrklevich EXPECT_EQ(3u, InstrMeta->InstructionSize);
14589c3c8c4SVlad Tsyrklevich EXPECT_TRUE(InstrMeta->Valid);
14689c3c8c4SVlad Tsyrklevich
14789c3c8c4SVlad Tsyrklevich NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);
14889c3c8c4SVlad Tsyrklevich EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));
14989c3c8c4SVlad Tsyrklevich PrevInstrMeta = InstrMeta;
15089c3c8c4SVlad Tsyrklevich
15189c3c8c4SVlad Tsyrklevich // 0xDEADBEEF + 6: sub $0x18, %rsp
15289c3c8c4SVlad Tsyrklevich InstrMeta = Analysis.getInstruction(0xDEADBEEF + 6);
15389c3c8c4SVlad Tsyrklevich EXPECT_NE(nullptr, InstrMeta);
15489c3c8c4SVlad Tsyrklevich EXPECT_EQ(NextInstrMeta, InstrMeta);
15589c3c8c4SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 6, InstrMeta->VMAddress);
15689c3c8c4SVlad Tsyrklevich EXPECT_EQ(4u, InstrMeta->InstructionSize);
15789c3c8c4SVlad Tsyrklevich EXPECT_TRUE(InstrMeta->Valid);
15889c3c8c4SVlad Tsyrklevich
15989c3c8c4SVlad Tsyrklevich NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);
16089c3c8c4SVlad Tsyrklevich EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));
16189c3c8c4SVlad Tsyrklevich PrevInstrMeta = InstrMeta;
16289c3c8c4SVlad Tsyrklevich
16389c3c8c4SVlad Tsyrklevich // 0xDEADBEEF + 10: movabs $0x4007c4, %rsi
16489c3c8c4SVlad Tsyrklevich InstrMeta = Analysis.getInstruction(0xDEADBEEF + 10);
16589c3c8c4SVlad Tsyrklevich EXPECT_NE(nullptr, InstrMeta);
16689c3c8c4SVlad Tsyrklevich EXPECT_EQ(NextInstrMeta, InstrMeta);
16789c3c8c4SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 10, InstrMeta->VMAddress);
16889c3c8c4SVlad Tsyrklevich EXPECT_EQ(10u, InstrMeta->InstructionSize);
16989c3c8c4SVlad Tsyrklevich EXPECT_TRUE(InstrMeta->Valid);
17089c3c8c4SVlad Tsyrklevich
17189c3c8c4SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));
17289c3c8c4SVlad Tsyrklevich EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));
17389c3c8c4SVlad Tsyrklevich PrevInstrMeta = InstrMeta;
17489c3c8c4SVlad Tsyrklevich
17589c3c8c4SVlad Tsyrklevich // 0xDEADBEEF + 20: (bad)
17689c3c8c4SVlad Tsyrklevich InstrMeta = Analysis.getInstruction(0xDEADBEEF + 20);
17789c3c8c4SVlad Tsyrklevich EXPECT_NE(nullptr, InstrMeta);
17889c3c8c4SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 20, InstrMeta->VMAddress);
17989c3c8c4SVlad Tsyrklevich EXPECT_EQ(1u, InstrMeta->InstructionSize);
18089c3c8c4SVlad Tsyrklevich EXPECT_FALSE(InstrMeta->Valid);
18189c3c8c4SVlad Tsyrklevich
18289c3c8c4SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));
18389c3c8c4SVlad Tsyrklevich EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));
18489c3c8c4SVlad Tsyrklevich
18589c3c8c4SVlad Tsyrklevich // 0xDEADBEEF + 21: rex.B (bad)
18689c3c8c4SVlad Tsyrklevich InstrMeta = Analysis.getInstruction(0xDEADBEEF + 21);
18789c3c8c4SVlad Tsyrklevich EXPECT_NE(nullptr, InstrMeta);
18889c3c8c4SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 21, InstrMeta->VMAddress);
18989c3c8c4SVlad Tsyrklevich EXPECT_EQ(2u, InstrMeta->InstructionSize);
19089c3c8c4SVlad Tsyrklevich EXPECT_FALSE(InstrMeta->Valid);
19189c3c8c4SVlad Tsyrklevich
19289c3c8c4SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));
19389c3c8c4SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta));
19489c3c8c4SVlad Tsyrklevich
19589c3c8c4SVlad Tsyrklevich // 0xDEADBEEF + 6: (bad) {%k1}
19689c3c8c4SVlad Tsyrklevich InstrMeta = Analysis.getInstruction(0xDEADBEEF + 23);
19789c3c8c4SVlad Tsyrklevich EXPECT_NE(nullptr, InstrMeta);
19889c3c8c4SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 23, InstrMeta->VMAddress);
19989c3c8c4SVlad Tsyrklevich EXPECT_EQ(5u, InstrMeta->InstructionSize);
20089c3c8c4SVlad Tsyrklevich EXPECT_FALSE(InstrMeta->Valid);
20189c3c8c4SVlad Tsyrklevich
20289c3c8c4SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));
20389c3c8c4SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta));
20489c3c8c4SVlad Tsyrklevich }
20589c3c8c4SVlad Tsyrklevich
TEST_F(BasicX86FileAnalysisTest,PrevAndNextFromBadInst)20606e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, PrevAndNextFromBadInst) {
207d9af383dSMitch Phillips if (!SuccessfullyInitialised)
2087fc87159SPaul Robinson GTEST_SKIP();
20989c3c8c4SVlad Tsyrklevich Analysis.parseSectionContents(
21089c3c8c4SVlad Tsyrklevich {
21189c3c8c4SVlad Tsyrklevich 0x90, // 0: nop
21289c3c8c4SVlad Tsyrklevich 0x2f, // 1: (bad)
21389c3c8c4SVlad Tsyrklevich 0x90 // 2: nop
21489c3c8c4SVlad Tsyrklevich },
21577fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
21689c3c8c4SVlad Tsyrklevich const auto &BadInstrMeta = Analysis.getInstructionOrDie(0xDEADBEEF + 1);
21789c3c8c4SVlad Tsyrklevich const auto *GoodInstrMeta =
21889c3c8c4SVlad Tsyrklevich Analysis.getPrevInstructionSequential(BadInstrMeta);
21989c3c8c4SVlad Tsyrklevich EXPECT_NE(nullptr, GoodInstrMeta);
22089c3c8c4SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF, GoodInstrMeta->VMAddress);
22189c3c8c4SVlad Tsyrklevich EXPECT_EQ(1u, GoodInstrMeta->InstructionSize);
22289c3c8c4SVlad Tsyrklevich
22389c3c8c4SVlad Tsyrklevich GoodInstrMeta = Analysis.getNextInstructionSequential(BadInstrMeta);
22489c3c8c4SVlad Tsyrklevich EXPECT_NE(nullptr, GoodInstrMeta);
22589c3c8c4SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 2, GoodInstrMeta->VMAddress);
22689c3c8c4SVlad Tsyrklevich EXPECT_EQ(1u, GoodInstrMeta->InstructionSize);
22789c3c8c4SVlad Tsyrklevich }
22889c3c8c4SVlad Tsyrklevich
TEST_F(BasicX86FileAnalysisTest,CFITrapTest)22906e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFITrapTest) {
230d9af383dSMitch Phillips if (!SuccessfullyInitialised)
2317fc87159SPaul Robinson GTEST_SKIP();
2320ee26324SVlad Tsyrklevich Analysis.parseSectionContents(
2330ee26324SVlad Tsyrklevich {
2340ee26324SVlad Tsyrklevich 0x90, // 0: nop
2350ee26324SVlad Tsyrklevich 0xb0, 0x00, // 1: mov $0x0, %al
2360ee26324SVlad Tsyrklevich 0x48, 0x89, 0xe5, // 3: mov %rsp, %rbp
2370ee26324SVlad Tsyrklevich 0x48, 0x83, 0xec, 0x18, // 6: sub $0x18, %rsp
2380ee26324SVlad Tsyrklevich 0x48, 0xbe, 0xc4, 0x07, 0x40,
2390ee26324SVlad Tsyrklevich 0x00, 0x00, 0x00, 0x00, 0x00, // 10: movabs $0x4007c4, %rsi
2400ee26324SVlad Tsyrklevich 0x2f, // 20: (bad)
2410ee26324SVlad Tsyrklevich 0x41, 0x0e, // 21: rex.B (bad)
2420ee26324SVlad Tsyrklevich 0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
2430ee26324SVlad Tsyrklevich 0x0f, 0x0b // 28: ud2
2440ee26324SVlad Tsyrklevich },
24577fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
2460ee26324SVlad Tsyrklevich
2470ee26324SVlad Tsyrklevich EXPECT_FALSE(Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF)));
2480ee26324SVlad Tsyrklevich EXPECT_FALSE(
2490ee26324SVlad Tsyrklevich Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 3)));
2500ee26324SVlad Tsyrklevich EXPECT_FALSE(
2510ee26324SVlad Tsyrklevich Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 6)));
2520ee26324SVlad Tsyrklevich EXPECT_FALSE(
2530ee26324SVlad Tsyrklevich Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 10)));
2540ee26324SVlad Tsyrklevich EXPECT_FALSE(
2550ee26324SVlad Tsyrklevich Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 20)));
2560ee26324SVlad Tsyrklevich EXPECT_FALSE(
2570ee26324SVlad Tsyrklevich Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 21)));
2580ee26324SVlad Tsyrklevich EXPECT_FALSE(
2590ee26324SVlad Tsyrklevich Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 23)));
2600ee26324SVlad Tsyrklevich EXPECT_TRUE(
2610ee26324SVlad Tsyrklevich Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 28)));
2620ee26324SVlad Tsyrklevich }
2630ee26324SVlad Tsyrklevich
TEST_F(BasicX86FileAnalysisTest,FallThroughTest)26406e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, FallThroughTest) {
265d9af383dSMitch Phillips if (!SuccessfullyInitialised)
2667fc87159SPaul Robinson GTEST_SKIP();
2670ee26324SVlad Tsyrklevich Analysis.parseSectionContents(
2680ee26324SVlad Tsyrklevich {
2690ee26324SVlad Tsyrklevich 0x90, // 0: nop
2700ee26324SVlad Tsyrklevich 0xb0, 0x00, // 1: mov $0x0, %al
2710ee26324SVlad Tsyrklevich 0x2f, // 3: (bad)
2720ee26324SVlad Tsyrklevich 0x0f, 0x0b, // 4: ud2
2730ee26324SVlad Tsyrklevich 0xff, 0x20, // 6: jmpq *(%rax)
2740ee26324SVlad Tsyrklevich 0xeb, 0x00, // 8: jmp +0
2750ee26324SVlad Tsyrklevich 0xe8, 0x45, 0xfe, 0xff, 0xff, // 10: callq [some loc]
2760ee26324SVlad Tsyrklevich 0xff, 0x10, // 15: callq *(rax)
2770ee26324SVlad Tsyrklevich 0x75, 0x00, // 17: jne +0
2780ee26324SVlad Tsyrklevich 0xc3, // 19: retq
2790ee26324SVlad Tsyrklevich },
28077fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
2810ee26324SVlad Tsyrklevich
2820ee26324SVlad Tsyrklevich EXPECT_TRUE(
2830ee26324SVlad Tsyrklevich Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF)));
2840ee26324SVlad Tsyrklevich EXPECT_TRUE(
2850ee26324SVlad Tsyrklevich Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 1)));
2860ee26324SVlad Tsyrklevich EXPECT_FALSE(
2870ee26324SVlad Tsyrklevich Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 3)));
2880ee26324SVlad Tsyrklevich EXPECT_FALSE(
2890ee26324SVlad Tsyrklevich Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 4)));
2900ee26324SVlad Tsyrklevich EXPECT_FALSE(
2910ee26324SVlad Tsyrklevich Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 6)));
2920ee26324SVlad Tsyrklevich EXPECT_FALSE(
2930ee26324SVlad Tsyrklevich Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 8)));
2940ee26324SVlad Tsyrklevich EXPECT_FALSE(
2950ee26324SVlad Tsyrklevich Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 10)));
2960ee26324SVlad Tsyrklevich EXPECT_FALSE(
2970ee26324SVlad Tsyrklevich Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 15)));
2980ee26324SVlad Tsyrklevich EXPECT_TRUE(
2990ee26324SVlad Tsyrklevich Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 17)));
3000ee26324SVlad Tsyrklevich EXPECT_FALSE(
3010ee26324SVlad Tsyrklevich Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 19)));
3020ee26324SVlad Tsyrklevich }
3030ee26324SVlad Tsyrklevich
TEST_F(BasicX86FileAnalysisTest,DefiniteNextInstructionTest)30406e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, DefiniteNextInstructionTest) {
305d9af383dSMitch Phillips if (!SuccessfullyInitialised)
3067fc87159SPaul Robinson GTEST_SKIP();
3070ee26324SVlad Tsyrklevich Analysis.parseSectionContents(
3080ee26324SVlad Tsyrklevich {
3090ee26324SVlad Tsyrklevich 0x90, // 0: nop
3100ee26324SVlad Tsyrklevich 0xb0, 0x00, // 1: mov $0x0, %al
3110ee26324SVlad Tsyrklevich 0x2f, // 3: (bad)
3120ee26324SVlad Tsyrklevich 0x0f, 0x0b, // 4: ud2
3130ee26324SVlad Tsyrklevich 0xff, 0x20, // 6: jmpq *(%rax)
3140ee26324SVlad Tsyrklevich 0xeb, 0x00, // 8: jmp 10 [+0]
3150ee26324SVlad Tsyrklevich 0xeb, 0x05, // 10: jmp 17 [+5]
3160ee26324SVlad Tsyrklevich 0xe8, 0x00, 0x00, 0x00, 0x00, // 12: callq 17 [+0]
3170ee26324SVlad Tsyrklevich 0xe8, 0x78, 0x56, 0x34, 0x12, // 17: callq 0x1234569f [+0x12345678]
3180ee26324SVlad Tsyrklevich 0xe8, 0x04, 0x00, 0x00, 0x00, // 22: callq 31 [+4]
3190ee26324SVlad Tsyrklevich 0xff, 0x10, // 27: callq *(rax)
3200ee26324SVlad Tsyrklevich 0x75, 0x00, // 29: jne 31 [+0]
3210ee26324SVlad Tsyrklevich 0x75, 0xe0, // 31: jne 1 [-32]
3220ee26324SVlad Tsyrklevich 0xc3, // 33: retq
3230ee26324SVlad Tsyrklevich 0xeb, 0xdd, // 34: jmp 1 [-35]
3240ee26324SVlad Tsyrklevich 0xeb, 0xdd, // 36: jmp 3 [-35]
3250ee26324SVlad Tsyrklevich 0xeb, 0xdc, // 38: jmp 4 [-36]
3260ee26324SVlad Tsyrklevich },
32777fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
3280ee26324SVlad Tsyrklevich
3290ee26324SVlad Tsyrklevich const auto *Current = Analysis.getInstruction(0xDEADBEEF);
3300ee26324SVlad Tsyrklevich const auto *Next = Analysis.getDefiniteNextInstruction(*Current);
3310ee26324SVlad Tsyrklevich EXPECT_NE(nullptr, Next);
3320ee26324SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 1, Next->VMAddress);
3330ee26324SVlad Tsyrklevich
3340ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 1);
3350ee26324SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
3360ee26324SVlad Tsyrklevich
3370ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 3);
3380ee26324SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
3390ee26324SVlad Tsyrklevich
3400ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 4);
3410ee26324SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
3420ee26324SVlad Tsyrklevich
3430ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 6);
3440ee26324SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
3450ee26324SVlad Tsyrklevich
3460ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 8);
3470ee26324SVlad Tsyrklevich Next = Analysis.getDefiniteNextInstruction(*Current);
3480ee26324SVlad Tsyrklevich EXPECT_NE(nullptr, Next);
3490ee26324SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 10, Next->VMAddress);
3500ee26324SVlad Tsyrklevich
3510ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 10);
3520ee26324SVlad Tsyrklevich Next = Analysis.getDefiniteNextInstruction(*Current);
3530ee26324SVlad Tsyrklevich EXPECT_NE(nullptr, Next);
3540ee26324SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 17, Next->VMAddress);
3550ee26324SVlad Tsyrklevich
3560ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 12);
3570ee26324SVlad Tsyrklevich Next = Analysis.getDefiniteNextInstruction(*Current);
3580ee26324SVlad Tsyrklevich EXPECT_NE(nullptr, Next);
3590ee26324SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 17, Next->VMAddress);
3600ee26324SVlad Tsyrklevich
3610ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 17);
3620ee26324SVlad Tsyrklevich // Note, definite next instruction address is out of range and should fail.
3630ee26324SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
3640ee26324SVlad Tsyrklevich Next = Analysis.getDefiniteNextInstruction(*Current);
3650ee26324SVlad Tsyrklevich
3660ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 22);
3670ee26324SVlad Tsyrklevich Next = Analysis.getDefiniteNextInstruction(*Current);
3680ee26324SVlad Tsyrklevich EXPECT_NE(nullptr, Next);
3690ee26324SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 31, Next->VMAddress);
3700ee26324SVlad Tsyrklevich
3710ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 27);
3720ee26324SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
3730ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 29);
3740ee26324SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
3750ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 31);
3760ee26324SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
3770ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 33);
3780ee26324SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
3790ee26324SVlad Tsyrklevich
3800ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 34);
3810ee26324SVlad Tsyrklevich Next = Analysis.getDefiniteNextInstruction(*Current);
3820ee26324SVlad Tsyrklevich EXPECT_NE(nullptr, Next);
3830ee26324SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 1, Next->VMAddress);
3840ee26324SVlad Tsyrklevich
3850ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 36);
3860ee26324SVlad Tsyrklevich EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
3870ee26324SVlad Tsyrklevich
3880ee26324SVlad Tsyrklevich Current = Analysis.getInstruction(0xDEADBEEF + 38);
3890ee26324SVlad Tsyrklevich Next = Analysis.getDefiniteNextInstruction(*Current);
3900ee26324SVlad Tsyrklevich EXPECT_NE(nullptr, Next);
3910ee26324SVlad Tsyrklevich EXPECT_EQ(0xDEADBEEF + 4, Next->VMAddress);
3920ee26324SVlad Tsyrklevich }
3930ee26324SVlad Tsyrklevich
TEST_F(BasicX86FileAnalysisTest,ControlFlowXRefsTest)39406e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, ControlFlowXRefsTest) {
395d9af383dSMitch Phillips if (!SuccessfullyInitialised)
3967fc87159SPaul Robinson GTEST_SKIP();
3970ee26324SVlad Tsyrklevich Analysis.parseSectionContents(
3980ee26324SVlad Tsyrklevich {
3990ee26324SVlad Tsyrklevich 0x90, // 0: nop
4000ee26324SVlad Tsyrklevich 0xb0, 0x00, // 1: mov $0x0, %al
4010ee26324SVlad Tsyrklevich 0x2f, // 3: (bad)
4020ee26324SVlad Tsyrklevich 0x0f, 0x0b, // 4: ud2
4030ee26324SVlad Tsyrklevich 0xff, 0x20, // 6: jmpq *(%rax)
4040ee26324SVlad Tsyrklevich 0xeb, 0x00, // 8: jmp 10 [+0]
4050ee26324SVlad Tsyrklevich 0xeb, 0x05, // 10: jmp 17 [+5]
4060ee26324SVlad Tsyrklevich 0xe8, 0x00, 0x00, 0x00, 0x00, // 12: callq 17 [+0]
4070ee26324SVlad Tsyrklevich 0xe8, 0x78, 0x56, 0x34, 0x12, // 17: callq 0x1234569f [+0x12345678]
4080ee26324SVlad Tsyrklevich 0xe8, 0x04, 0x00, 0x00, 0x00, // 22: callq 31 [+4]
4090ee26324SVlad Tsyrklevich 0xff, 0x10, // 27: callq *(rax)
4100ee26324SVlad Tsyrklevich 0x75, 0x00, // 29: jne 31 [+0]
4110ee26324SVlad Tsyrklevich 0x75, 0xe0, // 31: jne 1 [-32]
4120ee26324SVlad Tsyrklevich 0xc3, // 33: retq
4130ee26324SVlad Tsyrklevich 0xeb, 0xdd, // 34: jmp 1 [-35]
4140ee26324SVlad Tsyrklevich 0xeb, 0xdd, // 36: jmp 3 [-35]
4150ee26324SVlad Tsyrklevich 0xeb, 0xdc, // 38: jmp 4 [-36]
4160ee26324SVlad Tsyrklevich },
41777fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
4180ee26324SVlad Tsyrklevich const auto *InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF);
4190ee26324SVlad Tsyrklevich std::set<const Instr *> XRefs =
4200ee26324SVlad Tsyrklevich Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4210ee26324SVlad Tsyrklevich EXPECT_TRUE(XRefs.empty());
4220ee26324SVlad Tsyrklevich
4230ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 1);
4240ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4250ee26324SVlad Tsyrklevich EXPECT_THAT(XRefs, UnorderedElementsAre(
4260ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF)),
4270ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 31)),
4280ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 34))));
4290ee26324SVlad Tsyrklevich
4300ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 3);
4310ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4320ee26324SVlad Tsyrklevich EXPECT_THAT(XRefs, UnorderedElementsAre(
4330ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 1)),
4340ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 36))));
4350ee26324SVlad Tsyrklevich
4360ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 4);
4370ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4380ee26324SVlad Tsyrklevich EXPECT_THAT(XRefs, UnorderedElementsAre(
4390ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 38))));
4400ee26324SVlad Tsyrklevich
4410ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 6);
4420ee26324SVlad Tsyrklevich EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
4430ee26324SVlad Tsyrklevich
4440ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 8);
4450ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4460ee26324SVlad Tsyrklevich EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
4470ee26324SVlad Tsyrklevich
4480ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 10);
4490ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4500ee26324SVlad Tsyrklevich EXPECT_THAT(XRefs, UnorderedElementsAre(
4510ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 8))));
4520ee26324SVlad Tsyrklevich
4530ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 12);
4540ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4550ee26324SVlad Tsyrklevich EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
4560ee26324SVlad Tsyrklevich
4570ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 17);
4580ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4590ee26324SVlad Tsyrklevich EXPECT_THAT(XRefs, UnorderedElementsAre(
4600ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 10)),
4610ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 12))));
4620ee26324SVlad Tsyrklevich
4630ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 22);
4640ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4650ee26324SVlad Tsyrklevich EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
4660ee26324SVlad Tsyrklevich
4670ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 27);
4680ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4690ee26324SVlad Tsyrklevich EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
4700ee26324SVlad Tsyrklevich
4710ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 29);
4720ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4730ee26324SVlad Tsyrklevich EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
4740ee26324SVlad Tsyrklevich
4750ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 31);
4760ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4770ee26324SVlad Tsyrklevich EXPECT_THAT(XRefs, UnorderedElementsAre(
4780ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 22)),
4790ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 29))));
4800ee26324SVlad Tsyrklevich
4810ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 33);
4820ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4830ee26324SVlad Tsyrklevich EXPECT_THAT(XRefs, UnorderedElementsAre(
4840ee26324SVlad Tsyrklevich Field(&Instr::VMAddress, Eq(0xDEADBEEF + 31))));
4850ee26324SVlad Tsyrklevich
4860ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 34);
4870ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4880ee26324SVlad Tsyrklevich EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
4890ee26324SVlad Tsyrklevich
4900ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 36);
4910ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4920ee26324SVlad Tsyrklevich EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
4930ee26324SVlad Tsyrklevich
4940ee26324SVlad Tsyrklevich InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 38);
4950ee26324SVlad Tsyrklevich XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
4960ee26324SVlad Tsyrklevich EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
4970ee26324SVlad Tsyrklevich }
4980ee26324SVlad Tsyrklevich
TEST_F(BasicX86FileAnalysisTest,CFIProtectionInvalidTargets)49906e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionInvalidTargets) {
5005ff01cdcSMitch Phillips if (!SuccessfullyInitialised)
5017fc87159SPaul Robinson GTEST_SKIP();
5025ff01cdcSMitch Phillips Analysis.parseSectionContents(
5035ff01cdcSMitch Phillips {
5045ff01cdcSMitch Phillips 0x90, // 0: nop
5055ff01cdcSMitch Phillips 0x0f, 0x0b, // 1: ud2
5065ff01cdcSMitch Phillips 0x75, 0x00, // 3: jne 5 [+0]
5075ff01cdcSMitch Phillips },
50877fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
50977fc1f60SAlexey Lapshin GraphResult Result =
51077fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
5113b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
5123b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
51377fc1f60SAlexey Lapshin Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 1, 0x0});
5143b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
5153b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
51677fc1f60SAlexey Lapshin Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
5173b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
5183b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
51977fc1f60SAlexey Lapshin Result = GraphBuilder::buildFlowGraph(Analysis, {0x12345678, 0x0});
5203b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_INVALID_INSTRUCTION,
5213b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
5225ff01cdcSMitch Phillips }
5235ff01cdcSMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionBasicFallthroughToUd2)52406e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionBasicFallthroughToUd2) {
5255ff01cdcSMitch Phillips if (!SuccessfullyInitialised)
5267fc87159SPaul Robinson GTEST_SKIP();
5275ff01cdcSMitch Phillips Analysis.parseSectionContents(
5285ff01cdcSMitch Phillips {
5295ff01cdcSMitch Phillips 0x75, 0x02, // 0: jne 4 [+2]
5305ff01cdcSMitch Phillips 0x0f, 0x0b, // 2: ud2
5315ff01cdcSMitch Phillips 0xff, 0x10, // 4: callq *(%rax)
5325ff01cdcSMitch Phillips },
53377fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
53477fc1f60SAlexey Lapshin GraphResult Result =
53577fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
5363b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::PROTECTED,
5373b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
5385ff01cdcSMitch Phillips }
5395ff01cdcSMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionBasicJumpToUd2)54006e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionBasicJumpToUd2) {
5415ff01cdcSMitch Phillips if (!SuccessfullyInitialised)
5427fc87159SPaul Robinson GTEST_SKIP();
5435ff01cdcSMitch Phillips Analysis.parseSectionContents(
5445ff01cdcSMitch Phillips {
5455ff01cdcSMitch Phillips 0x75, 0x02, // 0: jne 4 [+2]
5465ff01cdcSMitch Phillips 0xff, 0x10, // 2: callq *(%rax)
5475ff01cdcSMitch Phillips 0x0f, 0x0b, // 4: ud2
5485ff01cdcSMitch Phillips },
54977fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
55077fc1f60SAlexey Lapshin GraphResult Result =
55177fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
5523b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::PROTECTED,
5533b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
5545ff01cdcSMitch Phillips }
5555ff01cdcSMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionDualPathUd2)55606e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualPathUd2) {
5575ff01cdcSMitch Phillips if (!SuccessfullyInitialised)
5587fc87159SPaul Robinson GTEST_SKIP();
5595ff01cdcSMitch Phillips Analysis.parseSectionContents(
5605ff01cdcSMitch Phillips {
5615ff01cdcSMitch Phillips 0x75, 0x03, // 0: jne 5 [+3]
5625ff01cdcSMitch Phillips 0x90, // 2: nop
5635ff01cdcSMitch Phillips 0xff, 0x10, // 3: callq *(%rax)
5645ff01cdcSMitch Phillips 0x0f, 0x0b, // 5: ud2
5655ff01cdcSMitch Phillips 0x75, 0xf9, // 7: jne 2 [-7]
5665ff01cdcSMitch Phillips 0x0f, 0x0b, // 9: ud2
5675ff01cdcSMitch Phillips },
56877fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
56977fc1f60SAlexey Lapshin GraphResult Result =
57077fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
5713b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::PROTECTED,
5723b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
5735ff01cdcSMitch Phillips }
5745ff01cdcSMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionDualPathSingleUd2)57506e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualPathSingleUd2) {
5765ff01cdcSMitch Phillips if (!SuccessfullyInitialised)
5777fc87159SPaul Robinson GTEST_SKIP();
5785ff01cdcSMitch Phillips Analysis.parseSectionContents(
5795ff01cdcSMitch Phillips {
5805ff01cdcSMitch Phillips 0x75, 0x05, // 0: jne 7 [+5]
5815ff01cdcSMitch Phillips 0x90, // 2: nop
5825ff01cdcSMitch Phillips 0xff, 0x10, // 3: callq *(%rax)
5835ff01cdcSMitch Phillips 0x75, 0xfb, // 5: jne 2 [-5]
5845ff01cdcSMitch Phillips 0x0f, 0x0b, // 7: ud2
5855ff01cdcSMitch Phillips },
58677fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
58777fc1f60SAlexey Lapshin GraphResult Result =
58877fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
5893b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::PROTECTED,
5903b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
5915ff01cdcSMitch Phillips }
5925ff01cdcSMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionDualFailLimitUpwards)59306e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualFailLimitUpwards) {
5945ff01cdcSMitch Phillips if (!SuccessfullyInitialised)
5957fc87159SPaul Robinson GTEST_SKIP();
5965ff01cdcSMitch Phillips Analysis.parseSectionContents(
5975ff01cdcSMitch Phillips {
5985ff01cdcSMitch Phillips 0x75, 0x06, // 0: jne 8 [+6]
5995ff01cdcSMitch Phillips 0x90, // 2: nop
6005ff01cdcSMitch Phillips 0x90, // 3: nop
6015ff01cdcSMitch Phillips 0x90, // 4: nop
6025ff01cdcSMitch Phillips 0x90, // 5: nop
6035ff01cdcSMitch Phillips 0xff, 0x10, // 6: callq *(%rax)
6045ff01cdcSMitch Phillips 0x0f, 0x0b, // 8: ud2
6055ff01cdcSMitch Phillips },
60677fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
6075ff01cdcSMitch Phillips uint64_t PrevSearchLengthForConditionalBranch =
6085ff01cdcSMitch Phillips SearchLengthForConditionalBranch;
6095ff01cdcSMitch Phillips SearchLengthForConditionalBranch = 2;
6105ff01cdcSMitch Phillips
61177fc1f60SAlexey Lapshin GraphResult Result =
61277fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 6, 0x0});
6133b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
6143b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
6155ff01cdcSMitch Phillips
6165ff01cdcSMitch Phillips SearchLengthForConditionalBranch = PrevSearchLengthForConditionalBranch;
6175ff01cdcSMitch Phillips }
6185ff01cdcSMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionDualFailLimitDownwards)61906e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualFailLimitDownwards) {
6205ff01cdcSMitch Phillips if (!SuccessfullyInitialised)
6217fc87159SPaul Robinson GTEST_SKIP();
6225ff01cdcSMitch Phillips Analysis.parseSectionContents(
6235ff01cdcSMitch Phillips {
6245ff01cdcSMitch Phillips 0x75, 0x02, // 0: jne 4 [+2]
6255ff01cdcSMitch Phillips 0xff, 0x10, // 2: callq *(%rax)
6265ff01cdcSMitch Phillips 0x90, // 4: nop
6275ff01cdcSMitch Phillips 0x90, // 5: nop
6285ff01cdcSMitch Phillips 0x90, // 6: nop
6295ff01cdcSMitch Phillips 0x90, // 7: nop
6305ff01cdcSMitch Phillips 0x0f, 0x0b, // 8: ud2
6315ff01cdcSMitch Phillips },
63277fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
6335ff01cdcSMitch Phillips uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
6345ff01cdcSMitch Phillips SearchLengthForUndef = 2;
6355ff01cdcSMitch Phillips
63677fc1f60SAlexey Lapshin GraphResult Result =
63777fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
6383b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,
6393b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
6405ff01cdcSMitch Phillips
6415ff01cdcSMitch Phillips SearchLengthForUndef = PrevSearchLengthForUndef;
6425ff01cdcSMitch Phillips }
6435ff01cdcSMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionGoodAndBadPaths)64406e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionGoodAndBadPaths) {
6455ff01cdcSMitch Phillips if (!SuccessfullyInitialised)
6467fc87159SPaul Robinson GTEST_SKIP();
6475ff01cdcSMitch Phillips Analysis.parseSectionContents(
6485ff01cdcSMitch Phillips {
6495ff01cdcSMitch Phillips 0xeb, 0x02, // 0: jmp 4 [+2]
6505ff01cdcSMitch Phillips 0x75, 0x02, // 2: jne 6 [+2]
6515ff01cdcSMitch Phillips 0xff, 0x10, // 4: callq *(%rax)
6525ff01cdcSMitch Phillips 0x0f, 0x0b, // 6: ud2
6535ff01cdcSMitch Phillips },
65477fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
65577fc1f60SAlexey Lapshin GraphResult Result =
65677fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
6573b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
6583b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
6595ff01cdcSMitch Phillips }
6605ff01cdcSMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionWithUnconditionalJumpInFallthrough)66106e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionWithUnconditionalJumpInFallthrough) {
6625ff01cdcSMitch Phillips if (!SuccessfullyInitialised)
6637fc87159SPaul Robinson GTEST_SKIP();
6645ff01cdcSMitch Phillips Analysis.parseSectionContents(
6655ff01cdcSMitch Phillips {
6665ff01cdcSMitch Phillips 0x75, 0x04, // 0: jne 6 [+4]
6675ff01cdcSMitch Phillips 0xeb, 0x00, // 2: jmp 4 [+0]
6685ff01cdcSMitch Phillips 0xff, 0x10, // 4: callq *(%rax)
6695ff01cdcSMitch Phillips 0x0f, 0x0b, // 6: ud2
6705ff01cdcSMitch Phillips },
67177fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
67277fc1f60SAlexey Lapshin GraphResult Result =
67377fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
6743b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::PROTECTED,
6753b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
6765ff01cdcSMitch Phillips }
6775ff01cdcSMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionComplexExample)67806e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionComplexExample) {
6795ff01cdcSMitch Phillips if (!SuccessfullyInitialised)
6807fc87159SPaul Robinson GTEST_SKIP();
6815ff01cdcSMitch Phillips // See unittests/GraphBuilder.cpp::BuildFlowGraphComplexExample for this
6825ff01cdcSMitch Phillips // graph.
6835ff01cdcSMitch Phillips Analysis.parseSectionContents(
6845ff01cdcSMitch Phillips {
6855ff01cdcSMitch Phillips 0x75, 0x12, // 0: jne 20 [+18]
6865ff01cdcSMitch Phillips 0xeb, 0x03, // 2: jmp 7 [+3]
6875ff01cdcSMitch Phillips 0x75, 0x10, // 4: jne 22 [+16]
6885ff01cdcSMitch Phillips 0x90, // 6: nop
6895ff01cdcSMitch Phillips 0x90, // 7: nop
6905ff01cdcSMitch Phillips 0x90, // 8: nop
6915ff01cdcSMitch Phillips 0xff, 0x10, // 9: callq *(%rax)
6925ff01cdcSMitch Phillips 0xeb, 0xfc, // 11: jmp 9 [-4]
6935ff01cdcSMitch Phillips 0x75, 0xfa, // 13: jne 9 [-6]
6945ff01cdcSMitch Phillips 0xe8, 0x78, 0x56, 0x34, 0x12, // 15: callq OUTOFBOUNDS [+0x12345678]
6955ff01cdcSMitch Phillips 0x90, // 20: nop
6965ff01cdcSMitch Phillips 0x90, // 21: nop
6975ff01cdcSMitch Phillips 0x0f, 0x0b, // 22: ud2
6985ff01cdcSMitch Phillips },
69977fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
700189ebb69SMitch Phillips uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
701189ebb69SMitch Phillips SearchLengthForUndef = 5;
70277fc1f60SAlexey Lapshin GraphResult Result =
70377fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});
7043b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
7053b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
706189ebb69SMitch Phillips SearchLengthForUndef = PrevSearchLengthForUndef;
707189ebb69SMitch Phillips }
708189ebb69SMitch Phillips
TEST_F(BasicX86FileAnalysisTest,UndefSearchLengthOneTest)70906e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, UndefSearchLengthOneTest) {
710*e6e69f3bSNico Weber if (!SuccessfullyInitialised)
711*e6e69f3bSNico Weber GTEST_SKIP();
712189ebb69SMitch Phillips Analysis.parseSectionContents(
713189ebb69SMitch Phillips {
714189ebb69SMitch Phillips 0x77, 0x0d, // 0x688118: ja 0x688127 [+12]
715189ebb69SMitch Phillips 0x48, 0x89, 0xdf, // 0x68811a: mov %rbx, %rdi
716189ebb69SMitch Phillips 0xff, 0xd0, // 0x68811d: callq *%rax
717189ebb69SMitch Phillips 0x48, 0x89, 0xdf, // 0x68811f: mov %rbx, %rdi
718189ebb69SMitch Phillips 0xe8, 0x09, 0x00, 0x00, 0x00, // 0x688122: callq 0x688130
719189ebb69SMitch Phillips 0x0f, 0x0b, // 0x688127: ud2
720189ebb69SMitch Phillips },
72177fc1f60SAlexey Lapshin {0x688118, 0x0});
722189ebb69SMitch Phillips uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
723189ebb69SMitch Phillips SearchLengthForUndef = 1;
72477fc1f60SAlexey Lapshin GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x68811d, 0x0});
7253b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::PROTECTED,
7263b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
727189ebb69SMitch Phillips SearchLengthForUndef = PrevSearchLengthForUndef;
728189ebb69SMitch Phillips }
729189ebb69SMitch Phillips
TEST_F(BasicX86FileAnalysisTest,UndefSearchLengthOneTestFarAway)73006e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, UndefSearchLengthOneTestFarAway) {
731*e6e69f3bSNico Weber if (!SuccessfullyInitialised)
732*e6e69f3bSNico Weber GTEST_SKIP();
733189ebb69SMitch Phillips Analysis.parseSectionContents(
734189ebb69SMitch Phillips {
735189ebb69SMitch Phillips 0x74, 0x73, // 0x7759eb: je 0x775a60
736189ebb69SMitch Phillips 0xe9, 0x1c, 0x04, 0x00, 0x00, 0x00, // 0x7759ed: jmpq 0x775e0e
737189ebb69SMitch Phillips },
73877fc1f60SAlexey Lapshin {0x7759eb, 0x0});
739189ebb69SMitch Phillips
740189ebb69SMitch Phillips Analysis.parseSectionContents(
741189ebb69SMitch Phillips {
742189ebb69SMitch Phillips 0x0f, 0x85, 0xb2, 0x03, 0x00, 0x00, // 0x775a56: jne 0x775e0e
743189ebb69SMitch Phillips 0x48, 0x83, 0xc3, 0xf4, // 0x775a5c: add $0xfffffffffffffff4,%rbx
744189ebb69SMitch Phillips 0x48, 0x8b, 0x7c, 0x24, 0x10, // 0x775a60: mov 0x10(%rsp),%rdi
745189ebb69SMitch Phillips 0x48, 0x89, 0xde, // 0x775a65: mov %rbx,%rsi
746189ebb69SMitch Phillips 0xff, 0xd1, // 0x775a68: callq *%rcx
747189ebb69SMitch Phillips },
74877fc1f60SAlexey Lapshin {0x775a56, 0x0});
749189ebb69SMitch Phillips
750189ebb69SMitch Phillips Analysis.parseSectionContents(
751189ebb69SMitch Phillips {
752189ebb69SMitch Phillips 0x0f, 0x0b, // 0x775e0e: ud2
753189ebb69SMitch Phillips },
75477fc1f60SAlexey Lapshin {0x775e0e, 0x0});
755189ebb69SMitch Phillips uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
756189ebb69SMitch Phillips SearchLengthForUndef = 1;
75777fc1f60SAlexey Lapshin GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
7583b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,
7593b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
760189ebb69SMitch Phillips SearchLengthForUndef = 2;
76177fc1f60SAlexey Lapshin Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
7623b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::PROTECTED,
7633b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
764189ebb69SMitch Phillips SearchLengthForUndef = 3;
76577fc1f60SAlexey Lapshin Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
7663b9ea32eSMitch Phillips EXPECT_EQ(CFIProtectionStatus::PROTECTED,
7673b9ea32eSMitch Phillips Analysis.validateCFIProtection(Result));
768189ebb69SMitch Phillips SearchLengthForUndef = PrevSearchLengthForUndef;
7695ff01cdcSMitch Phillips }
7705ff01cdcSMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionClobberSinglePathExplicit)77106e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathExplicit) {
7722e7be2a6SMitch Phillips if (!SuccessfullyInitialised)
7737fc87159SPaul Robinson GTEST_SKIP();
7742e7be2a6SMitch Phillips Analysis.parseSectionContents(
7752e7be2a6SMitch Phillips {
7762e7be2a6SMitch Phillips 0x75, 0x02, // 0: jne 4 [+2]
7772e7be2a6SMitch Phillips 0x0f, 0x0b, // 2: ud2
7782e7be2a6SMitch Phillips 0x48, 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %rax
7792e7be2a6SMitch Phillips 0xff, 0x10, // 10: callq *(%rax)
7802e7be2a6SMitch Phillips },
78177fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
78277fc1f60SAlexey Lapshin GraphResult Result =
78377fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 10, 0x0});
7842e7be2a6SMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
7852e7be2a6SMitch Phillips Analysis.validateCFIProtection(Result));
7862e7be2a6SMitch Phillips }
7872e7be2a6SMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionClobberSinglePathExplicit2)78806e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathExplicit2) {
7892e7be2a6SMitch Phillips if (!SuccessfullyInitialised)
7907fc87159SPaul Robinson GTEST_SKIP();
7912e7be2a6SMitch Phillips Analysis.parseSectionContents(
7922e7be2a6SMitch Phillips {
7932e7be2a6SMitch Phillips 0x75, 0x02, // 0: jne 4 [+2]
7942e7be2a6SMitch Phillips 0x0f, 0x0b, // 2: ud2
7952e7be2a6SMitch Phillips 0x48, 0x83, 0xc0, 0x00, // 4: add $0x0, %rax
7962e7be2a6SMitch Phillips 0xff, 0x10, // 8: callq *(%rax)
7972e7be2a6SMitch Phillips },
79877fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
79977fc1f60SAlexey Lapshin GraphResult Result =
80077fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});
8012e7be2a6SMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
8022e7be2a6SMitch Phillips Analysis.validateCFIProtection(Result));
8032e7be2a6SMitch Phillips }
8042e7be2a6SMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionClobberSinglePathImplicit)80506e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathImplicit) {
8062e7be2a6SMitch Phillips if (!SuccessfullyInitialised)
8077fc87159SPaul Robinson GTEST_SKIP();
8082e7be2a6SMitch Phillips Analysis.parseSectionContents(
8092e7be2a6SMitch Phillips {
8102e7be2a6SMitch Phillips 0x75, 0x02, // 0: jne 4 [+2]
8112e7be2a6SMitch Phillips 0x0f, 0x0b, // 2: ud2
8122e7be2a6SMitch Phillips 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %eax
8132e7be2a6SMitch Phillips 0xff, 0x10, // 9: callq *(%rax)
8142e7be2a6SMitch Phillips },
81577fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
81677fc1f60SAlexey Lapshin GraphResult Result =
81777fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});
8182e7be2a6SMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
8192e7be2a6SMitch Phillips Analysis.validateCFIProtection(Result));
8202e7be2a6SMitch Phillips }
8212e7be2a6SMitch Phillips
TEST_F(BasicX86FileAnalysisTest,CFIProtectionClobberDualPathImplicit)82206e7e579SJoel Galenson TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberDualPathImplicit) {
8232e7be2a6SMitch Phillips if (!SuccessfullyInitialised)
8247fc87159SPaul Robinson GTEST_SKIP();
8252e7be2a6SMitch Phillips Analysis.parseSectionContents(
8262e7be2a6SMitch Phillips {
8272e7be2a6SMitch Phillips 0x75, 0x04, // 0: jne 6 [+4]
8282e7be2a6SMitch Phillips 0x0f, 0x31, // 2: rdtsc (note: affects eax)
8292e7be2a6SMitch Phillips 0xff, 0x10, // 4: callq *(%rax)
8302e7be2a6SMitch Phillips 0x0f, 0x0b, // 6: ud2
8312e7be2a6SMitch Phillips 0x75, 0xf9, // 8: jne 2 [-7]
8322e7be2a6SMitch Phillips 0x0f, 0x0b, // 10: ud2
8332e7be2a6SMitch Phillips },
83477fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
83577fc1f60SAlexey Lapshin GraphResult Result =
83677fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
8372e7be2a6SMitch Phillips EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
8382e7be2a6SMitch Phillips Analysis.validateCFIProtection(Result));
8392e7be2a6SMitch Phillips }
8402e7be2a6SMitch Phillips
TEST_F(BasicAArch64FileAnalysisTest,AArch64BasicUnprotected)84106e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64BasicUnprotected) {
84206e7e579SJoel Galenson if (!SuccessfullyInitialised)
8437fc87159SPaul Robinson GTEST_SKIP();
84406e7e579SJoel Galenson Analysis.parseSectionContents(
84506e7e579SJoel Galenson {
84606e7e579SJoel Galenson 0x00, 0x01, 0x3f, 0xd6, // 0: blr x8
84706e7e579SJoel Galenson },
84877fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
84977fc1f60SAlexey Lapshin GraphResult Result =
85077fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
85106e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
85206e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
85306e7e579SJoel Galenson }
85406e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64BasicProtected)85506e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64BasicProtected) {
85606e7e579SJoel Galenson if (!SuccessfullyInitialised)
8577fc87159SPaul Robinson GTEST_SKIP();
85806e7e579SJoel Galenson Analysis.parseSectionContents(
85906e7e579SJoel Galenson {
86006e7e579SJoel Galenson 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
86106e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
86206e7e579SJoel Galenson 0x00, 0x01, 0x3f, 0xd6, // 8: blr x8
86306e7e579SJoel Galenson },
86477fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
86577fc1f60SAlexey Lapshin GraphResult Result =
86677fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});
86706e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::PROTECTED,
86806e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
86906e7e579SJoel Galenson }
87006e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64ClobberBasic)87106e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberBasic) {
87206e7e579SJoel Galenson if (!SuccessfullyInitialised)
8737fc87159SPaul Robinson GTEST_SKIP();
87406e7e579SJoel Galenson Analysis.parseSectionContents(
87506e7e579SJoel Galenson {
87606e7e579SJoel Galenson 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
87706e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
87806e7e579SJoel Galenson 0x08, 0x05, 0x00, 0x91, // 8: add x8, x8, #1
87906e7e579SJoel Galenson 0x00, 0x01, 0x3f, 0xd6, // 12: blr x8
88006e7e579SJoel Galenson },
88177fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
88277fc1f60SAlexey Lapshin GraphResult Result =
88377fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
88406e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
88506e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
88606e7e579SJoel Galenson }
88706e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64ClobberOneLoad)88806e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberOneLoad) {
88906e7e579SJoel Galenson if (!SuccessfullyInitialised)
8907fc87159SPaul Robinson GTEST_SKIP();
89106e7e579SJoel Galenson Analysis.parseSectionContents(
89206e7e579SJoel Galenson {
89306e7e579SJoel Galenson 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
89406e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
89506e7e579SJoel Galenson 0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
89606e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 12: br x1
89706e7e579SJoel Galenson },
89877fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
89977fc1f60SAlexey Lapshin GraphResult Result =
90077fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
90106e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::PROTECTED,
90206e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
90306e7e579SJoel Galenson }
90406e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64ClobberLoadAddGood)90506e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddGood) {
90606e7e579SJoel Galenson if (!SuccessfullyInitialised)
9077fc87159SPaul Robinson GTEST_SKIP();
90806e7e579SJoel Galenson Analysis.parseSectionContents(
90906e7e579SJoel Galenson {
91006e7e579SJoel Galenson 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
91106e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
91206e7e579SJoel Galenson 0x21, 0x04, 0x00, 0x91, // 8: add x1, x1, #1
91306e7e579SJoel Galenson 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
91406e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
91506e7e579SJoel Galenson },
91677fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
91777fc1f60SAlexey Lapshin GraphResult Result =
91877fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
91906e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::PROTECTED,
92006e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
92106e7e579SJoel Galenson }
92206e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64ClobberLoadAddBad)92306e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddBad) {
92406e7e579SJoel Galenson if (!SuccessfullyInitialised)
9257fc87159SPaul Robinson GTEST_SKIP();
92606e7e579SJoel Galenson Analysis.parseSectionContents(
92706e7e579SJoel Galenson {
92806e7e579SJoel Galenson 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
92906e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
93006e7e579SJoel Galenson 0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
93106e7e579SJoel Galenson 0x21, 0x04, 0x00, 0x91, // 12: add x1, x1, #1
93206e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
93306e7e579SJoel Galenson },
93477fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
93577fc1f60SAlexey Lapshin GraphResult Result =
93677fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
93706e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
93806e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
93906e7e579SJoel Galenson }
94006e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64ClobberLoadAddBad2)94106e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddBad2) {
94206e7e579SJoel Galenson if (!SuccessfullyInitialised)
9437fc87159SPaul Robinson GTEST_SKIP();
94406e7e579SJoel Galenson Analysis.parseSectionContents(
94506e7e579SJoel Galenson {
94606e7e579SJoel Galenson 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
94706e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
94806e7e579SJoel Galenson 0x29, 0x04, 0x00, 0x91, // 16: add x9, x1, #1
94906e7e579SJoel Galenson 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
95006e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
95106e7e579SJoel Galenson },
95277fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
95377fc1f60SAlexey Lapshin GraphResult Result =
95477fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
95506e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
95606e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
95706e7e579SJoel Galenson }
95806e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64ClobberTwoLoads)95906e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberTwoLoads) {
96006e7e579SJoel Galenson if (!SuccessfullyInitialised)
9617fc87159SPaul Robinson GTEST_SKIP();
96206e7e579SJoel Galenson Analysis.parseSectionContents(
96306e7e579SJoel Galenson {
96406e7e579SJoel Galenson 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
96506e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
96606e7e579SJoel Galenson 0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
96706e7e579SJoel Galenson 0x21, 0x08, 0x40, 0xf9, // 12: ldr x1, [x1,#16]
96806e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
96906e7e579SJoel Galenson },
97077fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
97177fc1f60SAlexey Lapshin GraphResult Result =
97277fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
97306e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
97406e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
97506e7e579SJoel Galenson }
97606e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64ClobberUnrelatedSecondLoad)97706e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberUnrelatedSecondLoad) {
97806e7e579SJoel Galenson if (!SuccessfullyInitialised)
9797fc87159SPaul Robinson GTEST_SKIP();
98006e7e579SJoel Galenson Analysis.parseSectionContents(
98106e7e579SJoel Galenson {
98206e7e579SJoel Galenson 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
98306e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
98406e7e579SJoel Galenson 0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
98506e7e579SJoel Galenson 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
98606e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
98706e7e579SJoel Galenson },
98877fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
98977fc1f60SAlexey Lapshin GraphResult Result =
99077fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
99106e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::PROTECTED,
99206e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
99306e7e579SJoel Galenson }
99406e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64ClobberUnrelatedLoads)99506e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberUnrelatedLoads) {
99606e7e579SJoel Galenson if (!SuccessfullyInitialised)
9977fc87159SPaul Robinson GTEST_SKIP();
99806e7e579SJoel Galenson Analysis.parseSectionContents(
99906e7e579SJoel Galenson {
100006e7e579SJoel Galenson 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
100106e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
100206e7e579SJoel Galenson 0x22, 0x09, 0x40, 0xf9, // 8: ldr x2, [x9,#16]
100306e7e579SJoel Galenson 0x22, 0x08, 0x40, 0xf9, // 12: ldr x2, [x1,#16]
100406e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
100506e7e579SJoel Galenson },
100677fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
100777fc1f60SAlexey Lapshin GraphResult Result =
100877fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
100906e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::PROTECTED,
101006e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
101106e7e579SJoel Galenson }
101206e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64GoodAndBadPaths)101306e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64GoodAndBadPaths) {
101406e7e579SJoel Galenson if (!SuccessfullyInitialised)
10157fc87159SPaul Robinson GTEST_SKIP();
101606e7e579SJoel Galenson Analysis.parseSectionContents(
101706e7e579SJoel Galenson {
101806e7e579SJoel Galenson 0x03, 0x00, 0x00, 0x14, // 0: b 12
101906e7e579SJoel Galenson 0x49, 0x00, 0x00, 0x54, // 4: b.ls 8
102006e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 8: brk #0x1
102106e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 12: br x1
102206e7e579SJoel Galenson },
102377fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
102477fc1f60SAlexey Lapshin GraphResult Result =
102577fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
102606e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
102706e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
102806e7e579SJoel Galenson }
102906e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64TwoPaths)103006e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPaths) {
103106e7e579SJoel Galenson if (!SuccessfullyInitialised)
10327fc87159SPaul Robinson GTEST_SKIP();
103306e7e579SJoel Galenson Analysis.parseSectionContents(
103406e7e579SJoel Galenson {
103506e7e579SJoel Galenson 0xc9, 0x00, 0x00, 0x54, // 0: b.ls 24
103606e7e579SJoel Galenson 0x21, 0x08, 0x40, 0xf9, // 4: ldr x1, [x1,#16]
103706e7e579SJoel Galenson 0x03, 0x00, 0x00, 0x14, // 8: b 12
103806e7e579SJoel Galenson 0x69, 0x00, 0x00, 0x54, // 12: b.ls 12
103906e7e579SJoel Galenson 0x21, 0x08, 0x40, 0xf9, // 16: ldr x1, [x1,#16]
104006e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 20: br x1
104106e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 24: brk #0x1
104206e7e579SJoel Galenson },
104377fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
104477fc1f60SAlexey Lapshin GraphResult Result =
104577fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 20, 0x0});
104606e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::PROTECTED,
104706e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
104806e7e579SJoel Galenson }
104906e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64TwoPathsBadLoad1)105006e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPathsBadLoad1) {
105106e7e579SJoel Galenson if (!SuccessfullyInitialised)
10527fc87159SPaul Robinson GTEST_SKIP();
105306e7e579SJoel Galenson Analysis.parseSectionContents(
105406e7e579SJoel Galenson {
105506e7e579SJoel Galenson 0xe9, 0x00, 0x00, 0x54, // 0: b.ls 28
105606e7e579SJoel Galenson 0x21, 0x08, 0x40, 0xf9, // 4: ldr x1, [x1,#16]
105706e7e579SJoel Galenson 0x21, 0x08, 0x40, 0xf9, // 8: ldr x1, [x1,#16]
105806e7e579SJoel Galenson 0x03, 0x00, 0x00, 0x14, // 12: b 12
105906e7e579SJoel Galenson 0x69, 0x00, 0x00, 0x54, // 16: b.ls 12
106006e7e579SJoel Galenson 0x21, 0x08, 0x40, 0xf9, // 20: ldr x1, [x1,#16]
106106e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 24: br x1
106206e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
106306e7e579SJoel Galenson },
106477fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
106577fc1f60SAlexey Lapshin GraphResult Result =
106677fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});
106706e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
106806e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
106906e7e579SJoel Galenson }
107006e7e579SJoel Galenson
TEST_F(BasicAArch64FileAnalysisTest,AArch64TwoPathsBadLoad2)107106e7e579SJoel Galenson TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPathsBadLoad2) {
107206e7e579SJoel Galenson if (!SuccessfullyInitialised)
10737fc87159SPaul Robinson GTEST_SKIP();
107406e7e579SJoel Galenson Analysis.parseSectionContents(
107506e7e579SJoel Galenson {
107606e7e579SJoel Galenson 0xe9, 0x00, 0x00, 0x54, // 0: b.ls 28
107706e7e579SJoel Galenson 0x21, 0x08, 0x40, 0xf9, // 4: ldr x1, [x1,#16]
107806e7e579SJoel Galenson 0x03, 0x00, 0x00, 0x14, // 8: b 12
107906e7e579SJoel Galenson 0x89, 0x00, 0x00, 0x54, // 12: b.ls 16
108006e7e579SJoel Galenson 0x21, 0x08, 0x40, 0xf9, // 16: ldr x1, [x1,#16]
108106e7e579SJoel Galenson 0x21, 0x08, 0x40, 0xf9, // 20: ldr x1, [x1,#16]
108206e7e579SJoel Galenson 0x20, 0x00, 0x1f, 0xd6, // 24: br x1
108306e7e579SJoel Galenson 0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
108406e7e579SJoel Galenson },
108577fc1f60SAlexey Lapshin {0xDEADBEEF, 0x0});
108677fc1f60SAlexey Lapshin GraphResult Result =
108777fc1f60SAlexey Lapshin GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});
108806e7e579SJoel Galenson EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
108906e7e579SJoel Galenson Analysis.validateCFIProtection(Result));
109006e7e579SJoel Galenson }
109106e7e579SJoel Galenson
109289c3c8c4SVlad Tsyrklevich } // anonymous namespace
109389c3c8c4SVlad Tsyrklevich } // end namespace cfi_verify
109489c3c8c4SVlad Tsyrklevich } // end namespace llvm
109589c3c8c4SVlad Tsyrklevich
main(int argc,char ** argv)109689c3c8c4SVlad Tsyrklevich int main(int argc, char **argv) {
109789c3c8c4SVlad Tsyrklevich ::testing::InitGoogleTest(&argc, argv);
109889c3c8c4SVlad Tsyrklevich llvm::cl::ParseCommandLineOptions(argc, argv);
109989c3c8c4SVlad Tsyrklevich
110089c3c8c4SVlad Tsyrklevich llvm::InitializeAllTargetInfos();
110189c3c8c4SVlad Tsyrklevich llvm::InitializeAllTargetMCs();
110289c3c8c4SVlad Tsyrklevich llvm::InitializeAllAsmParsers();
110389c3c8c4SVlad Tsyrklevich llvm::InitializeAllDisassemblers();
110489c3c8c4SVlad Tsyrklevich
110589c3c8c4SVlad Tsyrklevich return RUN_ALL_TESTS();
110689c3c8c4SVlad Tsyrklevich }
1107