test.cpp
Go to the documentation of this file.
1 //
2 // Bareflank Hypervisor
3 //
4 // Copyright (C) 2015 Assured Information Security, Inc.
5 // Author: Rian Quinn <quinnr@ainfosec.com>
6 // Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22 #include <test.h>
23 #include <constants.h>
24 #include <eh_frame_list.h>
25 #include <view_as_pointer.h>
26 
27 #include <sys/types.h>
28 #include <unistd.h>
29 
30 #include <link.h>
31 #include <string>
32 #include <fstream>
33 #include <streambuf>
34 
35 // -----------------------------------------------------------------------------
36 // A.out Load Address
37 // -----------------------------------------------------------------------------
38 
39 // The following code is needed to locate the load address of this application.
40 // If PIE is being used, the application will be relocated somewhere in memory
41 // and we need to use this relocation to identify were the eh_frame section
42 // is actually located
43 
44 uintptr_t g_offs = 0;
45 uintptr_t g_size = 0;
46 
47 static int
48 callback(struct dl_phdr_info *info, size_t size, void *data)
49 {
50  (void) size;
51  (void) data;
52  static auto once = false;
53 
54  if (once) return 0;
55  once = true;
56 
57  for (int i = 0; i < info->dlpi_phnum; i++)
58  {
59  if (info->dlpi_phdr[i].p_type == PT_LOAD)
60  {
61  g_offs = info->dlpi_addr;
62  break;
63  }
64  }
65 
66  return 0;
67 }
68 // -----------------------------------------------------------------------------
69 // Exception Handler Framework
70 // -----------------------------------------------------------------------------
71 
73 
74 extern "C" struct eh_frame_t *
76 {
77  g_eh_frame_list[0].addr = reinterpret_cast<void *>(g_offs);
78  g_eh_frame_list[0].size = g_size;
79 
80  return static_cast<struct eh_frame_t *>(g_eh_frame_list);
81 }
82 
83 // -----------------------------------------------------------------------------
84 // Test Implementation
85 // -----------------------------------------------------------------------------
86 
87 extern void *__eh_frame_start;
88 extern void *__eh_frame_end;
89 
91 {
92  dl_iterate_phdr(callback, nullptr);
93 
94  std::stringstream eh_frame_offs_ss;
95  std::stringstream eh_frame_size_ss;
96 
97  eh_frame_offs_ss << "readelf -SW /proc/" << getpid() << "/exe | grep \".eh_frame\" | grep -v \".eh_frame_hdr\" | awk '{print $4}' > offs.txt";
98  eh_frame_size_ss << "readelf -SW /proc/" << getpid() << "/exe | grep \".eh_frame\" | grep -v \".eh_frame_hdr\" | awk '{print $6}' > size.txt";
99 
100  system(eh_frame_offs_ss.str().c_str());
101  system(eh_frame_size_ss.str().c_str());
102 
103  auto &&offs_file = std::ifstream("offs.txt");
104  auto &&size_file = std::ifstream("size.txt");
105 
106  auto &&offs_str = std::string((std::istreambuf_iterator<char>(offs_file)), std::istreambuf_iterator<char>());
107  auto &&size_str = std::string((std::istreambuf_iterator<char>(size_file)), std::istreambuf_iterator<char>());
108 
109  std::remove("offs.txt");
110  std::remove("size.txt");
111 
112  std::cout << view_as_pointer(std::stoull(offs_str, nullptr, 16)) << '\n';
113  std::cout << view_as_pointer(std::stoull(size_str, nullptr, 16)) << '\n';
114 
115  g_offs += std::stoull(offs_str, nullptr, 16);
116  g_size += std::stoull(size_str, nullptr, 16);
117 }
118 
120 {
121  return true;
122 }
123 
125 {
126  return true;
127 }
128 
130 {
131  this->test_catch_all();
132  this->test_catch_bool();
133  this->test_catch_int();
134  this->test_catch_cstr();
135  this->test_catch_string();
136  this->test_catch_exception();
137  this->test_catch_custom_exception();
138  this->test_catch_multiple_catches_per_function();
139  this->test_catch_raii();
140  this->test_catch_throw_from_stream();
141  this->test_catch_nested_throw_in_catch();
142  this->test_catch_nested_throw_outside_catch();
143  this->test_catch_nested_throw_uncaught();
144  this->test_catch_nested_throw_rethrow();
145  this->test_catch_throw_with_lots_of_register_mods();
146 
147  return true;
148 }
149 
150 int
151 main(int argc, char *argv[])
152 {
153  return RUN_ALL_TESTS(bfunwind_ut);
154 }
bool list() override
Definition: test.cpp:129
int main(int argc, char *argv[])
Definition: test.cpp:221
int64_t unsigned long void * data
struct eh_frame_t * get_eh_frame_list() noexcept
Definition: test.cpp:75
uintptr_t g_offs
Definition: test.cpp:44
void * addr
Definition: eh_frame_list.h:45
#define MAX_NUM_MODULES
Definition: constants.h:177
constexpr const auto size
void uint64_t uint64_t uint64_t *rdx noexcept
#define RUN_ALL_TESTS(ut)
Definition: unittest.h:246
eh_frame_t g_eh_frame_list[MAX_NUM_MODULES]
Definition: test.cpp:72
const void * view_as_pointer(const T val)
pid_t getpid(void)
Definition: syscall.cpp:69
bool fini() override
Definition: test.cpp:124
bool init() override
Definition: test.cpp:119
void * __eh_frame_start
uint64_t size
Definition: eh_frame_list.h:46
uintptr_t g_size
Definition: test.cpp:45
bfunwind_ut()
Definition: test.cpp:90
void * __eh_frame_end