Basic scheduler + job
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define IDA_BASE 0x140000000
|
||||||
|
#define RVA(ADDR) (ADDR - IDA_BASE)
|
||||||
|
|
||||||
|
#define RVA_TASK_SCHEDULER RVA(0x1484A58E0) // "AllTaskSchedulerJobs"
|
||||||
|
#define OFF_SCHEDULER_JOBS 0xC8 // "TaskScheduler::Job:"
|
||||||
|
#define OFF_JOB_NAME 0xF0 // "{}({};{})"
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "offsets.h"
|
||||||
|
#include "../process.h"
|
||||||
|
|
||||||
|
namespace RBX {
|
||||||
|
class Scheduler {
|
||||||
|
private:
|
||||||
|
BYTE *addr;
|
||||||
|
const Process &proc;
|
||||||
|
public:
|
||||||
|
class Job {
|
||||||
|
private:
|
||||||
|
BYTE *addr;
|
||||||
|
const Process &proc;
|
||||||
|
public:
|
||||||
|
Job(BYTE *va, const Process &process) : addr(va), proc(process) {}
|
||||||
|
|
||||||
|
const BYTE * const VA() const { return addr; }
|
||||||
|
|
||||||
|
inline std::string getName() const {
|
||||||
|
BYTE *name_ptr = addr + OFF_JOB_NAME;
|
||||||
|
uint64_t length = proc.Read<uint64_t>(name_ptr + 8);
|
||||||
|
std::string name(length, '\0');
|
||||||
|
proc.ReadBytes(proc.Read<BYTE *>(name_ptr), (BYTE *)name.data(), length);
|
||||||
|
name[length] = 0;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Scheduler(BYTE *va, const Process &process) : addr(va), proc(process) {}
|
||||||
|
|
||||||
|
inline std::vector<Job> getJobs() const {
|
||||||
|
std::vector<Job> jobs;
|
||||||
|
BYTE *jobsStart = proc.Read<BYTE *>(addr + OFF_SCHEDULER_JOBS);
|
||||||
|
BYTE *jobsEnd = proc.Read<BYTE *>(addr + OFF_SCHEDULER_JOBS + 8);
|
||||||
|
for (BYTE *job = jobsStart; job != jobsEnd; job += 16) {
|
||||||
|
Job j(proc.Read<BYTE *>(job), proc);
|
||||||
|
jobs.push_back(j);
|
||||||
|
}
|
||||||
|
return jobs;
|
||||||
|
}
|
||||||
|
|
||||||
|
Job getJob(const std::string &name);
|
||||||
|
};
|
||||||
|
}
|
||||||
+14
-2
@@ -21,12 +21,12 @@ class Process {
|
|||||||
public:
|
public:
|
||||||
static DWORD findProcessByName(const std::wstring &name);
|
static DWORD findProcessByName(const std::wstring &name);
|
||||||
|
|
||||||
inline BYTE *imageBase(void) {
|
inline BYTE *imageBase(void) const {
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T Read(BYTE *addr) {
|
inline T Read(BYTE *addr) const {
|
||||||
T buf;
|
T buf;
|
||||||
SIZE_T bytesRead;
|
SIZE_T bytesRead;
|
||||||
NTSTATUS status = Nt::resolve<Nt::ReadVirtualMemory>("NtReadVirtualMemory")(proc, addr, &buf, sizeof(buf), &bytesRead);
|
NTSTATUS status = Nt::resolve<Nt::ReadVirtualMemory>("NtReadVirtualMemory")(proc, addr, &buf, sizeof(buf), &bytesRead);
|
||||||
@@ -36,6 +36,18 @@ class Process {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void ReadBytes(BYTE *addr, BYTE *buf, size_t bytes) const {
|
||||||
|
SIZE_T bytesRead;
|
||||||
|
NTSTATUS status = Nt::resolve<Nt::ReadVirtualMemory>("NtReadVirtualMemory")(proc, addr, buf, bytes, &bytesRead);
|
||||||
|
if (status < 0) {
|
||||||
|
throw std::runtime_error(std::format("Failed to read {} bytes from {:X}", bytes, uintptr_t(addr)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BYTE *VA(uintptr_t rva) const {
|
||||||
|
return base + rva;
|
||||||
|
}
|
||||||
|
|
||||||
inline Process(const std::wstring &name) {
|
inline Process(const std::wstring &name) {
|
||||||
pid = findProcessByName(name);
|
pid = findProcessByName(name);
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
|
|||||||
+10
-1
@@ -1,9 +1,18 @@
|
|||||||
#include "xrbx/xrbx.h"
|
#include "xrbx/xrbx.h"
|
||||||
|
#include "xrbx/engine/scheduler.h"
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Process rbx(L"notepad.exe");
|
Process rbx(L"RobloxPlayerBeta.exe");
|
||||||
std::cout << std::format("Image Base: {:X}", uintptr_t(rbx.imageBase())) << std::endl;
|
std::cout << std::format("Image Base: {:X}", uintptr_t(rbx.imageBase())) << std::endl;
|
||||||
|
RBX::Scheduler sched(rbx.Read<BYTE *>(rbx.VA(RVA_TASK_SCHEDULER)), rbx);
|
||||||
|
try {
|
||||||
|
for (const auto &job : sched.getJobs()) {
|
||||||
|
std::cout << std::format("Job {} @ {:x}", job.getName(), uintptr_t(job.VA())) << std::endl;
|
||||||
|
}
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
std::cout << "err: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user