Add testcases for disassembler
authorChristoph Egger <Christoph.Egger@fau.de>
Thu, 26 Mar 2015 16:43:24 +0000 (17:43 +0100)
committerChristoph Egger <Christoph.Egger@fau.de>
Thu, 26 Mar 2015 16:43:24 +0000 (17:43 +0100)
Testing basic functionality of the LLVM-based disassembler on amd64/elf
and amd64/MachO. More tests will follow as soon as I get reasonable test
binaries, we should at least also cover PE and arm (maybe ppc, mips, ..)

CMakeLists.txt
src/disassembler/llvm/tests/amd64LinuxDisassemblerTest.cxx [new file with mode: 0644]
src/disassembler/llvm/tests/amd64MachODisassemblerTest.cxx [new file with mode: 0644]
testdata/disassembler/binaries/crypt.clang.O2.amd64.elf [new file with mode: 0755]
testdata/disassembler/binaries/crypt.clang.O2.amd64.elf.frida [new file with mode: 0644]
testdata/disassembler/binaries/crypt.clang.O2.amd64.macho [new file with mode: 0755]
testdata/disassembler/binaries/crypt.clang.O2.amd64.macho.frida [new file with mode: 0644]

index c54380dd76dc17d8812553728fe7ffd5b88ac2eb..fabb0d9d07d43ab79dc478220455f1e988bfa026 100644 (file)
@@ -129,6 +129,8 @@ set(fridatest_SOURCES
   src/core/tests/BasicBlockTest.cxx
   src/core/tests/FunctionTest.cxx
   src/core/tests/CommentTest.cxx
+  src/disassembler/llvm/tests/amd64LinuxDisassemblerTest.cxx
+  src/disassembler/llvm/tests/amd64MachODisassemblerTest.cxx
   ${frida_SOURCES}
   )
 
diff --git a/src/disassembler/llvm/tests/amd64LinuxDisassemblerTest.cxx b/src/disassembler/llvm/tests/amd64LinuxDisassemblerTest.cxx
new file mode 100644 (file)
index 0000000..932f79a
--- /dev/null
@@ -0,0 +1,72 @@
+#include <gtest/gtest.h>
+#include <string>
+
+#include "core/InformationManager.hxx"
+#include "core/Function.hxx"
+#include "core/BasicBlock.hxx"
+#include "disassembler/llvm/LLVMDisassembler.hxx"
+
+extern char * TEST_DATA_DIRECTORY;
+
+static void testMainFunction(Function* main) {
+       ASSERT_NE(nullptr, main);
+       EXPECT_STREQ("main", main->getName().c_str());
+
+       auto blocks = main->blocks();
+       auto block = blocks.begin()->second;
+       EXPECT_EQ(4, blocks.size());
+       EXPECT_EQ(17, block->getInstructions().size());
+       EXPECT_EQ(0x4007ea, block->getNextBlock(0));
+       EXPECT_EQ(0x4007ce, block->getNextBlock(1));
+
+       EXPECT_TRUE(blocks.find(0x4007ea) != blocks.end());
+       EXPECT_TRUE(blocks.find(0x4007ce) != blocks.end());
+}
+
+static void testCheckFunction(Function* check) {
+       ASSERT_NE(nullptr, check);
+       EXPECT_STREQ("check", check->getName().c_str());
+
+       auto blocks = check->blocks();
+       auto block = blocks.begin()->second;
+       EXPECT_EQ(1, blocks.size());
+       EXPECT_EQ(29, block->getInstructions().size());
+       EXPECT_EQ(0x0, block->getNextBlock(0));
+       EXPECT_EQ(0x0, block->getNextBlock(1));
+}
+
+TEST(llvmDisassemblerTest, amd64LinuxOpenBinaryBasicStructure) {
+       SCOPED_TRACE("opening cryptsample.clang.amd64.elf");
+       InformationManager manager;
+
+       llvm::InitializeAllTargetInfos();
+       llvm::InitializeAllTargetMCs();
+       llvm::InitializeAllAsmParsers();
+       llvm::InitializeAllDisassemblers();
+
+       manager.reset(std::string(TEST_DATA_DIRECTORY)
+                     + "/disassembler/binaries/crypt.clang.O2.amd64.elf");
+
+       ASSERT_NE(nullptr, manager.getDisassembler());
+       EXPECT_EQ(0x4005F0, manager.getDisassembler()->entryAddress());
+       testCheckFunction(manager.getFunction(0x4006f0));
+       testMainFunction(manager.getFunction(0x400770));
+}
+
+TEST(llvmDisassemblerTest, amd64LinuxLoadBinaryBasicStructure) {
+       SCOPED_TRACE("loading cryptsample.clang.amd64.elf");
+       InformationManager manager;
+
+       llvm::InitializeAllTargetInfos();
+       llvm::InitializeAllTargetMCs();
+       llvm::InitializeAllAsmParsers();
+       llvm::InitializeAllDisassemblers();
+
+       manager.load(std::string(TEST_DATA_DIRECTORY)
+                     + "/disassembler/binaries/crypt.clang.O2.amd64.elf.frida");
+
+       ASSERT_NE(nullptr, manager.getDisassembler());
+       EXPECT_EQ(0x4005F0, manager.getDisassembler()->entryAddress());
+       testCheckFunction(manager.getFunction(0x4006f0));
+       testMainFunction(manager.getFunction(0x400770));
+}
diff --git a/src/disassembler/llvm/tests/amd64MachODisassemblerTest.cxx b/src/disassembler/llvm/tests/amd64MachODisassemblerTest.cxx
new file mode 100644 (file)
index 0000000..db7eaec
--- /dev/null
@@ -0,0 +1,72 @@
+#include <gtest/gtest.h>
+#include <string>
+
+#include "core/InformationManager.hxx"
+#include "core/Function.hxx"
+#include "core/BasicBlock.hxx"
+#include "disassembler/llvm/LLVMDisassembler.hxx"
+
+extern char * TEST_DATA_DIRECTORY;
+
+static void testMainFunction(Function* main) {
+       SCOPED_TRACE("main");
+       ASSERT_NE(nullptr, main);
+       EXPECT_STREQ("_main", main->getName().c_str());
+
+       auto blocks = main->blocks();
+       auto block = blocks.begin()->second;
+       EXPECT_EQ(6, blocks.size());
+       EXPECT_EQ(20, block->getInstructions().size());
+       EXPECT_EQ(0x100000EB2, block->getNextBlock(0));
+       EXPECT_EQ(0x100000E99, block->getNextBlock(1));
+
+       EXPECT_TRUE(blocks.find(0x100000EB2) != blocks.end());
+       EXPECT_TRUE(blocks.find(0x100000E99) != blocks.end());
+}
+
+static void testCheckFunction(Function* check) {
+       SCOPED_TRACE("check");
+       ASSERT_NE(nullptr, check);
+       EXPECT_STREQ("_check", check->getName().c_str());
+
+       auto blocks = check->blocks();
+       auto block = blocks.begin()->second;
+       EXPECT_EQ(1, blocks.size());
+       EXPECT_EQ(29, block->getInstructions().size());
+       EXPECT_EQ(0x0, block->getNextBlock(0));
+       EXPECT_EQ(0x0, block->getNextBlock(1));
+}
+
+TEST(llvmDisassemblerTest, amd64MachOOpenBinaryBasicStructure) {
+       SCOPED_TRACE("opening cryptsample.clang.amd64.macho");
+       InformationManager manager;
+
+       llvm::InitializeAllTargetInfos();
+       llvm::InitializeAllTargetMCs();
+       llvm::InitializeAllAsmParsers();
+       llvm::InitializeAllDisassemblers();
+
+       manager.reset(std::string(TEST_DATA_DIRECTORY)
+                     + "/disassembler/binaries/crypt.clang.O2.amd64.macho");
+
+       ASSERT_NE(nullptr, manager.getDisassembler());
+       testCheckFunction(manager.getFunction(0x100000db0));
+       testMainFunction(manager.getFunction(0x100000e30));
+}
+
+TEST(llvmDisassemblerTest, amd64MachOLoadBinaryBasicStructure) {
+       SCOPED_TRACE("loading cryptsample.clang.amd64.macho");
+       InformationManager manager;
+
+       llvm::InitializeAllTargetInfos();
+       llvm::InitializeAllTargetMCs();
+       llvm::InitializeAllAsmParsers();
+       llvm::InitializeAllDisassemblers();
+
+       manager.load(std::string(TEST_DATA_DIRECTORY)
+                     + "/disassembler/binaries/crypt.clang.O2.amd64.macho.frida");
+
+       ASSERT_NE(nullptr, manager.getDisassembler());
+       testCheckFunction(manager.getFunction(0x100000db0));
+       testMainFunction(manager.getFunction(0x100000e30));
+}
diff --git a/testdata/disassembler/binaries/crypt.clang.O2.amd64.elf b/testdata/disassembler/binaries/crypt.clang.O2.amd64.elf
new file mode 100755 (executable)
index 0000000..d5e8d0a
Binary files /dev/null and b/testdata/disassembler/binaries/crypt.clang.O2.amd64.elf differ
diff --git a/testdata/disassembler/binaries/crypt.clang.O2.amd64.elf.frida b/testdata/disassembler/binaries/crypt.clang.O2.amd64.elf.frida
new file mode 100644 (file)
index 0000000..e580ce7
Binary files /dev/null and b/testdata/disassembler/binaries/crypt.clang.O2.amd64.elf.frida differ
diff --git a/testdata/disassembler/binaries/crypt.clang.O2.amd64.macho b/testdata/disassembler/binaries/crypt.clang.O2.amd64.macho
new file mode 100755 (executable)
index 0000000..edadd3c
Binary files /dev/null and b/testdata/disassembler/binaries/crypt.clang.O2.amd64.macho differ
diff --git a/testdata/disassembler/binaries/crypt.clang.O2.amd64.macho.frida b/testdata/disassembler/binaries/crypt.clang.O2.amd64.macho.frida
new file mode 100644 (file)
index 0000000..4c7519d
Binary files /dev/null and b/testdata/disassembler/binaries/crypt.clang.O2.amd64.macho.frida differ