Skip to content

Commit

Permalink
move platform specific codes
Browse files Browse the repository at this point in the history
  • Loading branch information
Yangff committed Feb 21, 2024
1 parent e63543b commit 20624d0
Show file tree
Hide file tree
Showing 9 changed files with 1,097 additions and 2,001 deletions.
2 changes: 2 additions & 0 deletions deps/first/SinglePassSigScanner/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ option(UE4SS_${TARGET}_BUILD_SHARED "Build as a shared lib" OFF)

if (WIN32)
set(${TARGET}_Sources
"${CMAKE_CURRENT_SOURCE_DIR}/src/SinglePassSigScanner.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/SinglePassSigScannerWin32.cpp"
)
else()
set(${TARGET}_Sources
"${CMAKE_CURRENT_SOURCE_DIR}/src/SinglePassSigScanner.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/SinglePassSigScannerLinux.cpp"
)
endif()
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,351 @@
#pragma once

#include <array>
#include <functional>
#include <mutex>
#include <vector>

#include <SigScanner/Common.hpp>


#ifdef WIN32
#include "SinglePassSigScannerWin32.hpp"
#else
#include "SinglePassSigScannerLinux.hpp"
#endif
#endif

#define HI_NIBBLE(b) (((b) >> 4) & 0x0F)
#define LO_NIBBLE(b) ((b)&0x0F)

namespace RC
{
enum class ScanTarget
{
MainExe,

AIModule,
Analytics,
AnalyticsET,
AnimationCore,
AnimGraphRuntime,
AppFramework,
ApplicationCore,
AssetRegistry,
AudioCaptureCore,
AudioCaptureRtAudio,
AudioExtensions,
AudioMixer,
AudioMixerCore,
AudioMixerXAudio2,
AudioPlatformConfiguration,
AugmentedReality,
AVEncoder,
AVIWriter,
BuildPatchServices,
BuildSettings,
Cbor,
CEF3Utils,
Chaos,
ChaosCore,
ChaosSolverEngine,
ChaosSolvers,
CinematicCamera,
ClothingSystemRuntimeCommon,
ClothingSystemRuntimeInterface,
ClothingSystemRuntimeNv,
Core,
CoreUObject,
CrunchCompression,
D3D11RHI,
D3D12RHI,
Engine,
EngineMessages,
EngineSettings,
EyeTracker,
FieldSystemCore,
FieldSystemEngine,
FieldSystemSimulationCore,
Foliage,
GameplayMediaEncoder,
GameplayTags,
GameplayTasks,
GeometryCollectionCore,
GeometryCollectionEngine,
GeometryCollectionSimulationCore,
HeadMountedDisplay,
HTTP,
HttpNetworkReplayStreaming,
HTTPServer,
Icmp,
ImageCore,
ImageWrapper,
ImageWriteQueue,
InputCore,
InputDevice,
InstallBundleManager,
InstancedSplines,
InteractiveToolsFramework,
Json,
JsonUtilities,
Landscape,
LauncherCheck,
LauncherPlatform,
LevelSequence,
LocalFileNetworkReplayStreaming,
MaterialShaderQualitySettings,
Media,
MediaAssets,
MediaUtils,
MeshDescription,
MeshUtilitiesCommon,
Messaging,
MessagingCommon,
MoviePlayer,
MovieScene,
MovieSceneCapture,
MovieSceneTracks,
MRMesh,
NavigationSystem,
Navmesh,
NetCore,
Networking,
NetworkReplayStreaming,
NonRealtimeAudioRenderer,
NullDrv,
NullNetworkReplayStreaming,
OpenGLDrv,
Overlay,
PacketHandler,
PakFile,
PerfCounters,
PhysicsCore,
PhysicsSQ,
PhysXCooking,
PreLoadScreen,
Projects,
PropertyPath,
RawMesh,
ReliabilityHandlerComponent,
RenderCore,
Renderer,
RHI,
RSA,
SandboxFile,
Serialization,
SessionMessages,
SessionServices,
SignalProcessing,
Slate,
SlateCore,
SlateNullRenderer,
SlateRHIRenderer,
Sockets,
SoundFieldRendering,
SSL,
StaticMeshDescription,
StreamingPauseRendering,
SynthBenchmark,
TimeManagement,
TraceLog,
UELibSampleRate,
UMG,
VectorVM,
Voice,
Voronoi,
VulkanRHI,
WebBrowser,
WindowsPlatformFeatures,
XAudio2,

Max,
};

auto RC_SPSS_API ScanTargetToString(ScanTarget scan_target) -> std::string;
auto RC_SPSS_API ScanTargetToString(size_t scan_target) -> std::string;

class RC_SPSS_API ScanTargetArray
{
public:
std::array<ModuleInfo, static_cast<size_t>(ScanTarget::Max)> array{};

auto operator[](ScanTarget index) -> ModuleOS&;
};

// Static storage to be used across all sig scanner types
// At the moment the only scanner type that exists is SinglePassScanner
// In the future there might be a multi-threaded version of SinglePassScanner
class RC_SPSS_API SigScannerStaticData
{
public:
// Store all of the MODULEINFO structs for all of the scan targets
// Can a vector of something non-windows be stored here and then a static MODULEINFO can be created in the cpp file ?
static ScanTargetArray m_modules_info;
static bool m_is_modular;
};

struct RC_SPSS_API SignatureContainerLight
{
// The scanner will set this to whichever signature a match was found for
size_t index_into_signatures{};

// The scanner will set this to the address of the current match (if a match was found)
// This is guaranteed to be non-null when 'callable' is called
uint8_t* match_address{};
};

struct RC_SPSS_API SignatureData
{
std::string signature{};

// TODO: Add 'ScanTarget' in here and remove 'ScanTarget' from the 'start_scan' function

// The user-code can cast the custom data to their own enum type before using
// It will be zero-defaulted in the event of no custom data being supplied
int32_t custom_data{};

// A mask that's used for the StdFind scanning method.
std::string mask{};
};

class SignatureContainer
{
private:
// Member variables in this class shouldn't be mutable outside of the scanner internals
// They cannot simply be private because this class isn't part of the scanner
// They cannot be const because they need to be mutated by the scanner
// The solution is to make everything private and give the scanner access by using the 'friend' keyword
friend class SinglePassScanner;

private:
std::vector<SignatureData> signatures;
const std::function<bool(SignatureContainer&)> on_match_found;
const std::function<void(SignatureContainer&)> on_scan_finished;

// Whether to store the results and pass them to on_scan_completed
const bool store_results{};

// The scanner will store results in here if 'store_results' is true
std::vector<SignatureContainerLight> result_store{};

// True if the scan was successful, otherwise false
bool did_succeed{false};

// The scanner will use this to cancel all future calls to 'callable' if the 'callable' signaled
bool ignore{};

// The scanner will set this to whichever signature a match was found for
size_t index_into_signatures{};

// The scanner will set this to the address of the current match (if a match was found)
// This is guaranteed to be non-null when 'callable' is called
uint8_t* match_address{};

// The scanner will set this to the size of the signature that was matched
size_t match_signature_size{};

public:
template <typename OnMatchFound, typename OnScanFinished>
SignatureContainer(std::vector<SignatureData> sig_param, OnMatchFound on_match_found_param, OnScanFinished on_scan_finished_param)
: signatures(std::move(sig_param)), on_match_found(on_match_found_param), on_scan_finished(on_scan_finished_param)
{
}

template <typename OnMatchFound, typename OnScanFinished>
SignatureContainer(std::vector<SignatureData> sig_param, OnMatchFound on_match_found_param, OnScanFinished on_scan_finished_param, bool store_results_param)
: signatures(std::move(sig_param)), on_match_found(on_match_found_param), on_scan_finished(on_scan_finished_param), store_results(store_results_param)
{
}

public:
[[nodiscard]] auto get_match_address() const -> uint8_t*
{
return match_address;
}
[[nodiscard]] auto get_index_into_signatures() const -> size_t
{
return index_into_signatures;
}
[[nodiscard]] auto get_did_succeed() -> bool&
{
return did_succeed;
}
[[nodiscard]] auto get_did_succeed() const -> bool
{
return did_succeed;
}
[[nodiscard]] auto get_signatures() const -> const std::vector<SignatureData>&
{
return signatures;
}
[[nodiscard]] auto get_result_store() const -> const std::vector<SignatureContainerLight>&
{
return result_store;
}
[[nodiscard]] auto get_match_signature_size() const -> size_t
{
return match_signature_size;
}
};

class SinglePassScanner
{
private:
static std::mutex m_scanner_mutex;

public:
enum class ScanMethod
{
Scalar,
StdFind,
};

public:
RC_SPSS_API static uint32_t m_num_threads;
RC_SPSS_API static ScanMethod m_scan_method;

// The minimum size a module has to be for multi-threading to be enabled
// Smaller modules might increase the cost of scanning due to the cost of creating threads
RC_SPSS_API static uint32_t m_multithreading_module_size_threshold;

private:
RC_SPSS_API auto static string_to_vector(std::string_view signature) -> std::vector<int>;
RC_SPSS_API auto static string_to_vector(const std::vector<SignatureData>& signatures) -> std::vector<std::vector<int>>;
RC_SPSS_API auto static format_aob_strings(std::vector<SignatureContainer>& signature_containers) -> void;

RC_SPSS_API auto static get_system_info() -> SystemInfo;

public:
RC_SPSS_API auto static scanner_work_thread(uint8_t* start_address,
uint8_t* end_address,
SystemInfo& info,
std::vector<SignatureContainer>& signature_containers) -> void;
RC_SPSS_API auto static scanner_work_thread_scalar(uint8_t* start_address,
uint8_t* end_address,
SystemInfo& info,
std::vector<SignatureContainer>& signature_containers) -> void;
RC_SPSS_API auto static scanner_work_thread_stdfind(uint8_t* start_address,
uint8_t* end_address,
SystemInfo& info,
std::vector<SignatureContainer>& signature_containers) -> void;

using SignatureContainerMap = std::unordered_map<ScanTarget, std::vector<SignatureContainer>>;
RC_SPSS_API auto static start_scan(SignatureContainerMap& signature_containers) -> void;
RC_SPSS_API auto static string_scan(std::wstring_view string_to_scan_for, ScanTarget = ScanTarget::MainExe) -> void*;
};


namespace Platform {
// Get the start address of the system
auto get_start_address(SystemInfo &info) -> uint8_t*;

// Get the end address of the system
auto get_end_address(SystemInfo &info) -> uint8_t*;

// Get the size of the module
auto get_module_size(ModuleOS &info) -> uint32_t;

// Get the base address of the module
auto get_module_base(ModuleOS &info) -> uint8_t*;
}; // namespace Platform

}; // namespace RC
Loading

0 comments on commit 20624d0

Please sign in to comment.