This repository has been archived by the owner on Apr 13, 2021. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add source code for the Windows DynamoRIO debug client
- Loading branch information
1 parent
aa24afd
commit fa6509f
Showing
16 changed files
with
3,029 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright 2011-2016 Google Inc. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include "AbstractCommandReader.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
//// Copyright 2011-2016 Google Inc. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Defines the interface that must be implemented by classes that want to | ||
// receive IPC commands from the broker. | ||
#ifndef ABSTRACTCOMMANDREADER_H_ | ||
#define ABSTRACTCOMMANDREADER_H_ | ||
|
||
#include <memory> | ||
|
||
#include "drdebug.pb.h" | ||
|
||
class AbstractCommandReader { | ||
public: | ||
virtual std::unique_ptr<security::drdebug::Command> WaitForCommand() = 0; | ||
virtual bool SendResponse(const security::drdebug::Response& response) = 0; | ||
}; | ||
|
||
#endif // ABSTRACTCOMMANDREADER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
//// Copyright 2011-2016 Google Inc. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Provides BitReference class, which allows user to create a reference | ||
// to selected range of bits in a variable. | ||
#ifndef BITREFERENCE_H_ | ||
#define BITREFERENCE_H_ | ||
|
||
#include <cassert> | ||
|
||
// Creates a reference to bits [first_bit_pos; first_bit_pos + bit_size - 1] | ||
// from source variable | ||
// | ||
// Bit position X corresponds to the bit with value 2^X (X-th from the right, | ||
// counting from 0) | ||
// | ||
// It doesn't free source pointer in destructor | ||
// | ||
// T should be an unsigned integer type (unsigned is needed because we can | ||
// underflow in BitMask() method. | ||
template <class T> | ||
class BitReference { | ||
public: | ||
// Same as BitReference(source, 0, sizeof(T)*8) | ||
explicit BitReference(T* source); | ||
|
||
BitReference(T* source, int first_bit_pos, int bit_size); | ||
|
||
void SetReference(T* source, int first_bit_pos, int bit_size); | ||
|
||
T value() const; | ||
void set_value(T val); | ||
|
||
private: | ||
T* source_; | ||
int first_bit_pos_; | ||
int bit_size_; | ||
|
||
// Creates a bitmask with lowest bit_cnt bits set to 1 | ||
static T BitMask(int bit_cnt); | ||
}; | ||
|
||
template <class T> | ||
BitReference<T>::BitReference(T* source) { | ||
SetReference(source, 0, sizeof(T) * 8); | ||
} | ||
|
||
template <class T> | ||
BitReference<T>::BitReference(T* source, int first_bit_pos, int bit_size) { | ||
SetReference(source, first_bit_pos, bit_size); | ||
} | ||
|
||
template <class T> | ||
void BitReference<T>::SetReference(T* source, int first_bit_pos, int bit_size) { | ||
assert(first_bit_pos >= 0 && first_bit_pos < sizeof(T) * 8); | ||
assert(first_bit_pos + bit_size <= sizeof(T) * 8); | ||
source_ = source; | ||
first_bit_pos_ = first_bit_pos; | ||
bit_size_ = bit_size; | ||
} | ||
|
||
template <class T> | ||
T BitReference<T>::value() const { | ||
return ((*source_) >> first_bit_pos_) & BitMask(bit_size_); | ||
} | ||
|
||
template <class T> | ||
void BitReference<T>::set_value(T val) { | ||
T val_mask = BitMask(bit_size_); | ||
T mask = ~(val_mask << first_bit_pos_); | ||
(*source_) = (((*source_) & mask) | ((val & val_mask) << first_bit_pos_)); | ||
} | ||
|
||
template <class T> | ||
T BitReference<T>::BitMask(int bit_cnt) { | ||
// We need it to solve the problem with bit_cnt >= 32 (1 << 32 == 1) | ||
if (bit_cnt >= sizeof(T) * 8) | ||
return (T)0 - 1; | ||
else | ||
return ((T)1 << bit_cnt) - 1; | ||
} | ||
|
||
#endif // BITREFERENCE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Copyright 2011-2016 Google Inc. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Provides BreakpointInfo, which holds breakpoint's parameters. | ||
#ifndef BREAKPOINTINFO_H_ | ||
#define BREAKPOINTINFO_H_ | ||
|
||
#include <functional> | ||
#include <memory> | ||
|
||
#include "common.h" | ||
|
||
// Note that instances of this class define an operator== that only takes the | ||
// breakpoint id into account and ignores other fields. | ||
class BreakpointInfo { | ||
public: | ||
BreakpointInfo(breakpoint_id_t id, bool auto_resume, bool send_registers) : | ||
: id_(id), auto_resume_(auto_resume), send_registers_(send_registers) {} | ||
|
||
breakpoint_id_t id() const { return id_; } | ||
bool auto_resume() const { return auto_resume_; } | ||
bool send_registers() const { return send_registers_; } | ||
|
||
bool operator==(const BreakpointInfo& other) const { | ||
return id_ == other.id_; | ||
} | ||
|
||
typedef std::function<bool(const std::unique_ptr<BreakpointInfo>&)> | ||
BreakpointComparator; | ||
|
||
// Returns a function which matches the thread with a given id. | ||
// Intended for use with STL functions, e.g. std::remove_if. | ||
static BreakpointComparator MakeBreakpointIdComparator(breakpoint_id_t id) { | ||
return [id](const std::unique_ptr<BreakpointInfo>& t) | ||
-> bool { return t->id() == id; }; | ||
} | ||
|
||
private: | ||
breakpoint_id_t id_; | ||
bool auto_resume_; | ||
bool send_registers_; | ||
}; | ||
|
||
#endif // BREAKPOINTINFO_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# Copyright 2011-2016 Google Inc. All Rights Reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
cmake_minimum_required (VERSION 2.8) | ||
# Make file for Dynamorio debugger client DLL. | ||
project(dynamorio_client) | ||
|
||
# Find dynamoRIO and set global options. | ||
include(FindProtobuf) | ||
find_package(Protobuf REQUIRED) | ||
find_package(DynamoRIO REQUIRED) | ||
|
||
include_directories(${PROTOBUF_INCLUDE_DIR}) | ||
|
||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") | ||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") | ||
|
||
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS drdebug.proto) | ||
|
||
foreach(PROTO_HDR ${PROTO_HDRS}) | ||
get_filename_component(HDR_DIR ${PROTO_HDR} DIRECTORY) | ||
include_directories(${HDR_DIR}) | ||
endforeach(PROTO_HDR) | ||
|
||
# Makes dynamic libraries (e.g. dr. memory) known to clients without having to | ||
# copy them to the bin32 directory. | ||
set(DynamoRIO_RPATH ON) | ||
|
||
add_library(dynamorio_client SHARED | ||
dynamorio_client.cc | ||
common.h | ||
WinPipeCommandReader.cc | ||
WinPipeCommandReader.h | ||
AbstractCommandReader.cc | ||
AbstractCommandReader.h | ||
BitReference.h | ||
DebugState.h | ||
DebugState.cc | ||
ScopedLocker.h | ||
BreakpointInfo.cc | ||
BreakpointInfo.h | ||
${PROTO_HDRS} | ||
${PROTO_SRCS}) | ||
|
||
target_link_libraries(dynamorio_client ${PROTOBUF_LIBRARIES}) | ||
|
||
# Configure dynamorio_client client. | ||
configure_DynamoRIO_client(dynamorio_client) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2011-2016 Google Inc. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include "DebugState.h" | ||
|
||
DebugState::DebugState() : state_(NOT_SET) { | ||
mutex_ = dr_mutex_create(); | ||
} | ||
|
||
DebugState::~DebugState() { | ||
dr_mutex_destroy(mutex_); | ||
} | ||
|
||
void DebugState::Lock() { | ||
dr_mutex_lock(mutex_); | ||
} | ||
|
||
void DebugState::Unlock() { | ||
dr_mutex_unlock(mutex_); | ||
} | ||
|
||
security::drdebug::ExceptionAction DebugState::GetExceptionAction( | ||
exception_code_t exc_code) { | ||
auto it = exception_actions_.find(exc_code); | ||
if (it == exception_actions_.end()) { | ||
return security::drdebug::ExceptionAction::HALT; | ||
} | ||
return it->second; | ||
} | ||
|
||
void DebugState::SetExceptionAction(exception_code_t exc_code, | ||
security::drdebug::ExceptionAction action) { | ||
exception_actions_[exc_code] = action; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
//// Copyright 2011-2016 Google Inc. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Provides DebugState, holds current debugger state and manages state | ||
// transitions. It holds only the part of debugger state that is shared | ||
// between DynamoRIO callbacks and debugger loop, thus needs access | ||
// synchronization. | ||
#ifndef DEBUGSTATE_H_ | ||
#define DEBUGSTATE_H_ | ||
|
||
#include <map> | ||
#include <memory> | ||
#include <set> | ||
#include <vector> | ||
|
||
#include "BreakpointInfo.h" | ||
#include "common.h" | ||
#include "dr_api.h" | ||
#include "drdebug.pb.h" | ||
|
||
class DebugState { | ||
public: | ||
enum State { | ||
NOT_SET, // Default value after DebugState construction. | ||
RUNNING, // Debuggee is currently running. | ||
WAITING, // Waiting after BP hit/exception. | ||
HALTED, // Halted by user, waiting for resume. | ||
EXITING, // After receiving exit_event, but before termination. | ||
}; | ||
|
||
DebugState(); | ||
~DebugState(); | ||
|
||
// Acquire internal mutex | ||
void Lock(); | ||
|
||
// Free internal mutex | ||
void Unlock(); | ||
|
||
security::drdebug::ExceptionAction GetExceptionAction( | ||
exception_code_t exc_code); | ||
void SetExceptionAction(exception_code_t exc_code, | ||
security::drdebug::ExceptionAction action); | ||
|
||
// Getters/setters | ||
State state() const { return state_; } | ||
|
||
void set_state(State new_state) { state_ = new_state; } | ||
|
||
std::set<app_pc>& breakpoint_addresses() { return breakpoint_addresses_; } | ||
|
||
std::map<app_pc, std::vector<std::unique_ptr<BreakpointInfo>>>& | ||
breakpoints() { | ||
return breakpoints_; | ||
} | ||
|
||
std::vector<thread_id_t>& debuggee_threads() { return debugee_threads_; } | ||
|
||
// No copy/assignment | ||
DebugState(const DebugState&) = delete; | ||
DebugState& operator =(const DebugState&) = delete; | ||
|
||
private: | ||
// Mutex for accessing fields | ||
void* mutex_; | ||
// Current state of debugged process | ||
State state_; | ||
// All debuggee addresses with breakpoints | ||
std::set<app_pc> breakpoint_addresses_; | ||
// Maps debuggee adress to a list of breakpoints id set on it | ||
// We need a pointer, not an object, because we rely on that the info struct | ||
// address won't change (we pass it in clean call to BPHit handler) | ||
std::map<app_pc, std::vector<std::unique_ptr<BreakpointInfo>>> breakpoints_; | ||
// Maps exception codes to its handling action | ||
std::map<exception_code_t, security::drdebug::ExceptionAction> | ||
exception_actions_; | ||
// List of all debugee threads | ||
std::vector<thread_id_t> debugee_threads_; | ||
}; | ||
|
||
#endif // DEBUGSTATE_H_ |
Oops, something went wrong.