um timer
This commit is contained in:
donnaskiez 2024-01-23 00:02:59 +11:00 committed by GitHub
parent 7e4adf3712
commit 2a316ff33d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 248 additions and 2 deletions

View file

@ -8,4 +8,16 @@
#include <vector>
#define LOG_INFO(fmt, ...) printf("[+] " fmt "\n", ##__VA_ARGS__)
#define LOG_ERROR(fmt, ...) printf("[-] " fmt "\n", ##__VA_ARGS__)
um-rewrite-final
#define LOG_ERROR(fmt, ...) printf("[-] " fmt "\n", ##__VA_ARGS__)
#define ABSOLUTE(wait) (wait)
#define RELATIVE(wait) (-(wait))
#define NANOSECONDS(nanos) (((signed __int64)(nanos)) / 100L)
#define MICROSECONDS(micros) (((signed __int64)(micros)) * NANOSECONDS(1000L))
#define MILLISECONDS(milli) (((signed __int64)(milli)) * MICROSECONDS(1000L))
#define SECONDS(seconds) (((signed __int64)(seconds)) * MILLISECONDS(1000L))
=======
#define LOG_ERROR(fmt, ...) printf("[-] " fmt "\n", ##__VA_ARGS__)
master

View file

@ -10,9 +10,34 @@ dispatcher::dispatcher::dispatcher(LPCWSTR driver_name,
: thread_pool(DISPATCHER_THREAD_COUNT),
k_interface(driver_name, message_queue) {}
um-rewrite-final
void dispatcher::dispatcher::timer_test_callback() {
LOG_INFO("Timer callback invoked from dispatcher class!!");
}
void dispatcher::dispatcher::init_timer_callbacks() {
this->timers.insert_callback(
std::bind(&dispatcher::dispatcher::timer_test_callback, this), 10, 10);
}
void dispatcher::dispatcher::run_timer_thread() {
thread_pool.queue_job([this]() { this->timers.run_timer_thread(); });
}
void dispatcher::dispatcher::run_io_port_thread() {
thread_pool.queue_job([this]() { k_interface.run_completion_port(); });
}
void dispatcher::dispatcher::run() {
helper::generate_rand_seed();
this->init_timer_callbacks();
this->run_timer_thread();
this->run_io_port_thread();
=======
void dispatcher::dispatcher::run() {
helper::generate_rand_seed();
thread_pool.queue_job([this]() { k_interface.run_completion_port(); });
master
while (true) {
this->issue_kernel_job();
helper::sleep_thread(DISPATCH_LOOP_SLEEP_TIME);

View file

@ -2,6 +2,10 @@
#include "threadpool.h"
um-rewrite-final
#include "timer.h"
=======
master
#include "../kernel_interface/kernel_interface.h"
namespace dispatcher {
@ -11,10 +15,21 @@ static const int KERNEL_DISPATCH_FUNCTION_COUNT = 11;
static const int DISPATCHER_THREAD_COUNT = 4;
class dispatcher {
um-rewrite-final
timer timers;
=======
master
thread_pool thread_pool;
kernel_interface::kernel_interface k_interface;
void issue_kernel_job();
um-rewrite-final
void timer_test_callback();
void init_timer_callbacks();
void run_timer_thread();
void run_io_port_thread();
=======
master
public:
dispatcher(LPCWSTR driver_name, client::message_queue &queue);

View file

@ -0,0 +1,89 @@
#include "timer.h"
#include "../common.h"
#include "../helper.h"
dispatcher::timer::timer() { LOG_INFO("constructor"); }
dispatcher::timer::~timer() {}
HANDLE dispatcher::timer::create_timer_object() {
return CreateWaitableTimer(nullptr, false, nullptr);
}
bool dispatcher::timer::set_timer_object(HANDLE handle, LARGE_INTEGER *due_time,
unsigned long period) {
return SetWaitableTimer(handle, due_time, period, nullptr, nullptr, false) > 0
? true
: false;
}
bool dispatcher::timer::insert_callback(std::function<void()> routine,
int due_time_seconds,
int period_seconds) {
std::lock_guard<std::mutex> lock(this->lock);
std::optional<int> index = this->find_free_handle_index();
if (!index.has_value()) {
LOG_ERROR("No free event handles available. Unable to create timer.");
return false;
}
HANDLE handle = create_timer_object();
if (!handle) {
LOG_ERROR("CreateWaitableTimer failed with status %x", GetLastError());
set_callback_inactive(index.value());
return false;
}
callback *cb = &this->callbacks[index.value()];
cb->callback_routine = routine;
cb->due_time.QuadPart = helper::seconds_to_nanoseconds(due_time_seconds);
cb->period = helper::seconds_to_milliseconds(period_seconds);
this->handles[index.value()] = handle;
if (!set_timer_object(handle, &cb->due_time, cb->period)) {
LOG_ERROR("SetWaitableTimer failed with status %x", GetLastError());
close_handle_entry(handle);
set_callback_inactive(index.value());
}
this->active_callbacks++;
return true;
}
/* assumes lock is held by caller */
std::optional<int> dispatcher::timer::find_free_handle_index() {
for (int index = 0; index < MAXIMUM_WAIT_OBJECTS; index++) {
if (callbacks[index].in_use == false) {
callbacks[index].in_use = true;
return index;
}
}
return {};
}
void dispatcher::timer::close_handle_entry(HANDLE handle) {
for (auto &entry : handles) {
if (entry == handle) {
entry = INVALID_HANDLE_VALUE;
CloseHandle(entry);
}
}
}
void dispatcher::timer::set_callback_inactive(int index) {
this->callbacks[index].in_use = false;
}
void dispatcher::timer::dispatch_callback_for_index(unsigned long index) {
this->callbacks[index].callback_routine();
}
void dispatcher::timer::run_timer_thread() {
while (true) {
unsigned long index = WaitForMultipleObjects(
this->active_callbacks, reinterpret_cast<HANDLE *>(&handles), false,
INFINITE);
this->dispatch_callback_for_index(index);
}
}

65
module/dispatcher/timer.h Normal file
View file

@ -0,0 +1,65 @@
#pragma once
#include <Windows.h>
#include <array>
#include <functional>
#include <mutex>
#include <optional>
#include <vector>
/*
* array of handles which we pass to WaitForMultipleEvents
*
* needa do this rather then use the dedicated apc routien pointer in set timer
* cos u cant just take a pointer to a member function for some reason lol like
* tf
*
* this returns an index into the array
*
* setup a vector containing the job routine for the associated handle, then
* call that job.
*
* If we activate another handle in the handles array, the next time the current
* event is signalled and we are invoked, only then should we insert new
* requests. This means we should implement some queue where new timer objects
* are inserted into the queue, then when the current even is invoked, we can
* recall WaitForMultipleObjects with the updated array count.
*/
namespace dispatcher {
constexpr int HANDLE_AVAILABLE = 0;
constexpr int HANDLE_NOT_AVAILABLE = 1;
class timer {
struct callback {
bool in_use;
std::function<void()> callback_routine;
LARGE_INTEGER due_time;
unsigned long period;
};
std::optional<int> find_free_handle_index();
void close_handle_entry(HANDLE handle);
void dispatch_callback_for_index(unsigned long index);
HANDLE create_timer_object();
bool set_timer_object(HANDLE handle, LARGE_INTEGER *due_time,
unsigned long period);
void set_callback_inactive(int index);
public:
std::mutex lock;
std::array<HANDLE, MAXIMUM_WAIT_OBJECTS> handles;
std::array<callback, MAXIMUM_WAIT_OBJECTS> callbacks;
int active_callbacks;
timer();
~timer();
bool insert_callback(std::function<void()> routine, int due_time_seconds,
int period_seconds);
void run_timer_thread();
};
} // namespace dispatcher

View file

@ -166,4 +166,16 @@ void helper::print_kernel_report(void *buffer) {
LOG_INFO("Invalid report type.");
break;
}
}
um-rewrite-final
}
unsigned __int64 helper::seconds_to_nanoseconds(int seconds) {
return ABSOLUTE(SECONDS(seconds));
}
unsigned __int32 helper::seconds_to_milliseconds(int seconds) {
return seconds * 1000;
}
=======
}
master

View file

@ -9,4 +9,9 @@ void sleep_thread(int seconds);
kernel_interface::report_id get_kernel_report_type(void *buffer);
int get_report_id_from_buffer(void *buffer);
void print_kernel_report(void *buffer);
um-rewrite-final
unsigned __int64 seconds_to_nanoseconds(int seconds);
unsigned __int32 seconds_to_milliseconds(int seconds);
=======
master
} // namespace helper

View file

@ -216,6 +216,9 @@ public:
void verify_process_module_executable_regions();
void initiate_apc_stackwalk();
void send_pending_irp();
um-rewrite-final
=======
void query_deferred_reports();
master
};
} // namespace kernel_interface

View file

@ -140,6 +140,10 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
um-rewrite-final
<ClCompile Include="dispatcher\timer.cpp" />
=======
master
<ClCompile Include="helper.cpp" />
<ClCompile Include="imports.cpp" />
<ClCompile Include="module.cpp" />
@ -156,6 +160,10 @@
<ClInclude Include="dispatcher\dispatcher.h" />
<ClInclude Include="dispatcher\threadpool.h" />
<ClInclude Include="common.h" />
um-rewrite-final
<ClInclude Include="dispatcher\timer.h" />
=======
master
<ClInclude Include="helper.h" />
<ClInclude Include="imports.h" />
<ClInclude Include="kernel_interface\kernel_interface.h" />

View file

@ -42,6 +42,12 @@
<ClCompile Include="imports.cpp">
<Filter>Source Files</Filter>
</ClCompile>
um-rewrite-final
<ClCompile Include="dispatcher\timer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
=======
master
</ItemGroup>
<ItemGroup>
<ClInclude Include="common.h">
@ -71,5 +77,11 @@
<ClInclude Include="imports.h">
<Filter>Header Files</Filter>
</ClInclude>
um-rewrite-final
<ClInclude Include="dispatcher\timer.h">
<Filter>Header Files</Filter>
</ClInclude>
=======
master
</ItemGroup>
</Project>