Work in progress signature cache map loading and parsing

This commit is contained in:
Kawe Mazidjatari 2022-12-01 22:47:39 +01:00
parent 41dbf77715
commit f999372f37
12 changed files with 761 additions and 40 deletions

View File

@ -112,6 +112,7 @@
#include "game/client/viewrender.h"
#endif // !DEDICATED
#include "public/edict.h"
#include "public/utility/binstream.h"
#ifndef DEDICATED
#include "public/idebugoverlay.h"
#include "inputsystem/inputsystem.h"
@ -472,11 +473,60 @@ void CheckCPU() // Respawn's engine and our SDK utilize POPCNT, SSE3 and SSSE3 (
}
}
#include "protoc/sig_map.pb.h"
bool SigDB_Init()
{
CIOStream sigDbStream("bin\\startup.smap", CIOStream::Mode_t::READ);
if (!sigDbStream.IsReadable())
{
return false;
}
if (!sigDbStream.GetSize() > sizeof(SigDBHeader_t))
{
return false;
}
SigDBHeader_t sigDbHeader;
sigDbHeader.m_nMagic = sigDbStream.Read<int>();
if (sigDbHeader.m_nMagic != SIGDB_MAGIC)
{
return false;
}
sigDbHeader.m_nVersion = sigDbStream.Read<int>();
if (sigDbHeader.m_nMagic != SIGDB_VERSION)
{
return false;
}
sigDbHeader.m_FileTime = sigDbStream.Read<FILETIME>();
vector<uint8_t> vData;
size_t nSize = (static_cast<size_t>(sigDbStream.GetSize()) - sizeof(SigDBHeader_t));
vData.resize(nSize);
uint8_t* pBuf = vData.data();
sigDbStream.Read<uint8_t*>(pBuf, nSize);
if (!g_SigCache.m_Cache.ParseFromArray(pBuf, nSize))
{
return false;
}
return true;
}
void DetourInit() // Run the sigscan
{
bool bLogAdr = (strstr(GetCommandLineA(), "-sig_toconsole") != nullptr);
bool bInitDivider = false;
g_SigCache.m_bInitialized = SigDB_Init();
for (const IDetour* pDetour : vDetour)
{
pDetour->GetCon(); // Constants.
@ -493,6 +543,8 @@ void DetourInit() // Run the sigscan
pDetour->GetAdr();
}
}
g_SigCache.WriteCache();
}
void DetourAddress() // Test the sigscan results
{

View File

@ -86,6 +86,7 @@
#include "public/utility/utility.h"
#include "public/utility/memaddr.h"
#include "public/utility/module.h"
#include "public/utility/sigcache.h"
#include "public/utility/httplib.h"
#include "public/utility/vdf_parser.h"
@ -107,6 +108,7 @@ inline CModule g_RadAudioSystemDll = CModule("mileswin64.dll");
#else // No DirectX and Miles imports.
inline CModule g_GameDll = CModule("r5apex_ds.exe");
#endif // !DEDICATED
inline CSigCache g_SigCache;
#define VAR_NAME(varName) #varName

278
r5dev/protoc/sig_map.pb.cc Normal file
View File

@ -0,0 +1,278 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: sig_map.proto
#include "sig_map.pb.h"
#include <algorithm>
#include <thirdparty/protobuf/io/coded_stream.h>
#include <thirdparty/protobuf/extension_set.h>
#include <thirdparty/protobuf/wire_format_lite.h>
#include <thirdparty/protobuf/io/zero_copy_stream_impl_lite.h>
// @@protoc_insertion_point(includes)
#include <thirdparty/protobuf/port_def.inc>
PROTOBUF_PRAGMA_INIT_SEG
constexpr SigMap_Pb_SMapEntry_DoNotUse::SigMap_Pb_SMapEntry_DoNotUse(
::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized){}
struct SigMap_Pb_SMapEntry_DoNotUseDefaultTypeInternal {
constexpr SigMap_Pb_SMapEntry_DoNotUseDefaultTypeInternal()
: _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
~SigMap_Pb_SMapEntry_DoNotUseDefaultTypeInternal() {}
union {
SigMap_Pb_SMapEntry_DoNotUse _instance;
};
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT SigMap_Pb_SMapEntry_DoNotUseDefaultTypeInternal _SigMap_Pb_SMapEntry_DoNotUse_default_instance_;
constexpr SigMap_Pb::SigMap_Pb(
::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
: smap_(){}
struct SigMap_PbDefaultTypeInternal {
constexpr SigMap_PbDefaultTypeInternal()
: _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
~SigMap_PbDefaultTypeInternal() {}
union {
SigMap_Pb _instance;
};
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT SigMap_PbDefaultTypeInternal _SigMap_Pb_default_instance_;
// ===================================================================
SigMap_Pb_SMapEntry_DoNotUse::SigMap_Pb_SMapEntry_DoNotUse() {}
SigMap_Pb_SMapEntry_DoNotUse::SigMap_Pb_SMapEntry_DoNotUse(::PROTOBUF_NAMESPACE_ID::Arena* arena)
: SuperType(arena) {}
void SigMap_Pb_SMapEntry_DoNotUse::MergeFrom(const SigMap_Pb_SMapEntry_DoNotUse& other) {
MergeFromInternal(other);
}
// ===================================================================
class SigMap_Pb::_Internal {
public:
};
SigMap_Pb::SigMap_Pb(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::MessageLite(arena, is_message_owned),
smap_(arena) {
SharedCtor();
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:SigMap_Pb)
}
SigMap_Pb::SigMap_Pb(const SigMap_Pb& from)
: ::PROTOBUF_NAMESPACE_ID::MessageLite() {
_internal_metadata_.MergeFrom<std::string>(from._internal_metadata_);
smap_.MergeFrom(from.smap_);
// @@protoc_insertion_point(copy_constructor:SigMap_Pb)
}
inline void SigMap_Pb::SharedCtor() {
}
SigMap_Pb::~SigMap_Pb() {
// @@protoc_insertion_point(destructor:SigMap_Pb)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<std::string>();
}
inline void SigMap_Pb::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
}
void SigMap_Pb::ArenaDtor(void* object) {
SigMap_Pb* _this = reinterpret_cast< SigMap_Pb* >(object);
(void)_this;
}
void SigMap_Pb::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
}
void SigMap_Pb::SetCachedSize(int size) const {
_cached_size_.Set(size);
}
void SigMap_Pb::Clear() {
// @@protoc_insertion_point(message_clear_start:SigMap_Pb)
uint32_t cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
smap_.Clear();
_internal_metadata_.Clear<std::string>();
}
const char* SigMap_Pb::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
while (!ctx->Done(&ptr)) {
uint32_t tag;
ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
switch (tag >> 3) {
// map<string, uint64> sMap = 1;
case 1:
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
ptr -= 1;
do {
ptr += 1;
ptr = ctx->ParseMessage(&smap_, ptr);
CHK_(ptr);
if (!ctx->DataAvailable(ptr)) break;
} while (::PROTOBUF_NAMESPACE_ID::internal::ExpectTag<10>(ptr));
} else
goto handle_unusual;
continue;
default:
goto handle_unusual;
} // switch
handle_unusual:
if ((tag == 0) || ((tag & 7) == 4)) {
CHK_(ptr);
ctx->SetLastTag(tag);
goto message_done;
}
ptr = UnknownFieldParse(
tag,
_internal_metadata_.mutable_unknown_fields<std::string>(),
ptr, ctx);
CHK_(ptr != nullptr);
} // while
message_done:
return ptr;
failure:
ptr = nullptr;
goto message_done;
#undef CHK_
}
uint8_t* SigMap_Pb::_InternalSerialize(
uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
// @@protoc_insertion_point(serialize_to_array_start:SigMap_Pb)
uint32_t cached_has_bits = 0;
(void) cached_has_bits;
// map<string, uint64> sMap = 1;
if (!this->_internal_smap().empty()) {
typedef ::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >::const_pointer
ConstPtr;
typedef ConstPtr SortItem;
typedef ::PROTOBUF_NAMESPACE_ID::internal::CompareByDerefFirst<SortItem> Less;
struct Utf8Check {
static void Check(ConstPtr p) {
(void)p;
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
p->first.data(), static_cast<int>(p->first.length()),
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
"SigMap_Pb.SMapEntry.key");
}
};
if (stream->IsSerializationDeterministic() &&
this->_internal_smap().size() > 1) {
::std::unique_ptr<SortItem[]> items(
new SortItem[this->_internal_smap().size()]);
typedef ::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >::size_type size_type;
size_type n = 0;
for (::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >::const_iterator
it = this->_internal_smap().begin();
it != this->_internal_smap().end(); ++it, ++n) {
items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);
}
::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());
for (size_type i = 0; i < n; i++) {
target = SigMap_Pb_SMapEntry_DoNotUse::Funcs::InternalSerialize(1, items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second, target, stream);
Utf8Check::Check(&(*items[static_cast<ptrdiff_t>(i)]));
}
} else {
for (::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >::const_iterator
it = this->_internal_smap().begin();
it != this->_internal_smap().end(); ++it) {
target = SigMap_Pb_SMapEntry_DoNotUse::Funcs::InternalSerialize(1, it->first, it->second, target, stream);
Utf8Check::Check(&(*it));
}
}
}
if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
target = stream->WriteRaw(_internal_metadata_.unknown_fields<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(),
static_cast<int>(_internal_metadata_.unknown_fields<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target);
}
// @@protoc_insertion_point(serialize_to_array_end:SigMap_Pb)
return target;
}
size_t SigMap_Pb::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:SigMap_Pb)
size_t total_size = 0;
uint32_t cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
// map<string, uint64> sMap = 1;
total_size += 1 *
::PROTOBUF_NAMESPACE_ID::internal::FromIntSize(this->_internal_smap_size());
for (::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >::const_iterator
it = this->_internal_smap().begin();
it != this->_internal_smap().end(); ++it) {
total_size += SigMap_Pb_SMapEntry_DoNotUse::Funcs::ByteSizeLong(it->first, it->second);
}
if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
total_size += _internal_metadata_.unknown_fields<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size();
}
int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size);
SetCachedSize(cached_size);
return total_size;
}
void SigMap_Pb::CheckTypeAndMergeFrom(
const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) {
MergeFrom(*::PROTOBUF_NAMESPACE_ID::internal::DownCast<const SigMap_Pb*>(
&from));
}
void SigMap_Pb::MergeFrom(const SigMap_Pb& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:SigMap_Pb)
GOOGLE_DCHECK_NE(&from, this);
uint32_t cached_has_bits = 0;
(void) cached_has_bits;
smap_.MergeFrom(from.smap_);
_internal_metadata_.MergeFrom<std::string>(from._internal_metadata_);
}
void SigMap_Pb::CopyFrom(const SigMap_Pb& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:SigMap_Pb)
if (&from == this) return;
Clear();
MergeFrom(from);
}
bool SigMap_Pb::IsInitialized() const {
return true;
}
void SigMap_Pb::InternalSwap(SigMap_Pb* other) {
using std::swap;
_internal_metadata_.InternalSwap(&other->_internal_metadata_);
smap_.InternalSwap(&other->smap_);
}
std::string SigMap_Pb::GetTypeName() const {
return "SigMap_Pb";
}
// @@protoc_insertion_point(namespace_scope)
PROTOBUF_NAMESPACE_OPEN
template<> PROTOBUF_NOINLINE ::SigMap_Pb_SMapEntry_DoNotUse* Arena::CreateMaybeMessage< ::SigMap_Pb_SMapEntry_DoNotUse >(Arena* arena) {
return Arena::CreateMessageInternal< ::SigMap_Pb_SMapEntry_DoNotUse >(arena);
}
template<> PROTOBUF_NOINLINE ::SigMap_Pb* Arena::CreateMaybeMessage< ::SigMap_Pb >(Arena* arena) {
return Arena::CreateMessageInternal< ::SigMap_Pb >(arena);
}
PROTOBUF_NAMESPACE_CLOSE
// @@protoc_insertion_point(global_scope)
#include <thirdparty/protobuf/port_undef.inc>

287
r5dev/protoc/sig_map.pb.h Normal file
View File

@ -0,0 +1,287 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: sig_map.proto
#ifndef GOOGLE_PROTOBUF_INCLUDED_sig_5fmap_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_sig_5fmap_2eproto
#include <limits>
#include <string>
#include <thirdparty/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3019000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3019004 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <thirdparty/protobuf/port_undef.inc>
#include <thirdparty/protobuf/io/coded_stream.h>
#include <thirdparty/protobuf/arena.h>
#include <thirdparty/protobuf/arenastring.h>
#include <thirdparty/protobuf/generated_message_table_driven.h>
#include <thirdparty/protobuf/generated_message_util.h>
#include <thirdparty/protobuf/metadata_lite.h>
#include <thirdparty/protobuf/message_lite.h>
#include <thirdparty/protobuf/repeated_field.h> // IWYU pragma: export
#include <thirdparty/protobuf/extension_set.h> // IWYU pragma: export
#include <thirdparty/protobuf/map.h> // IWYU pragma: export
#include <thirdparty/protobuf/map_entry_lite.h>
#include <thirdparty/protobuf/map_field_lite.h>
// @@protoc_insertion_point(includes)
#include <thirdparty/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_sig_5fmap_2eproto
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
} // namespace internal
PROTOBUF_NAMESPACE_CLOSE
// Internal implementation detail -- do not use these members.
struct TableStruct_sig_5fmap_2eproto {
static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[2]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
static const uint32_t offsets[];
};
class SigMap_Pb;
struct SigMap_PbDefaultTypeInternal;
extern SigMap_PbDefaultTypeInternal _SigMap_Pb_default_instance_;
class SigMap_Pb_SMapEntry_DoNotUse;
struct SigMap_Pb_SMapEntry_DoNotUseDefaultTypeInternal;
extern SigMap_Pb_SMapEntry_DoNotUseDefaultTypeInternal _SigMap_Pb_SMapEntry_DoNotUse_default_instance_;
PROTOBUF_NAMESPACE_OPEN
template<> ::SigMap_Pb* Arena::CreateMaybeMessage<::SigMap_Pb>(Arena*);
template<> ::SigMap_Pb_SMapEntry_DoNotUse* Arena::CreateMaybeMessage<::SigMap_Pb_SMapEntry_DoNotUse>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
// ===================================================================
class SigMap_Pb_SMapEntry_DoNotUse : public ::PROTOBUF_NAMESPACE_ID::internal::MapEntryLite<SigMap_Pb_SMapEntry_DoNotUse,
std::string, uint64_t,
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING,
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT64> {
public:
typedef ::PROTOBUF_NAMESPACE_ID::internal::MapEntryLite<SigMap_Pb_SMapEntry_DoNotUse,
std::string, uint64_t,
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING,
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT64> SuperType;
SigMap_Pb_SMapEntry_DoNotUse();
explicit constexpr SigMap_Pb_SMapEntry_DoNotUse(
::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
explicit SigMap_Pb_SMapEntry_DoNotUse(::PROTOBUF_NAMESPACE_ID::Arena* arena);
void MergeFrom(const SigMap_Pb_SMapEntry_DoNotUse& other);
static const SigMap_Pb_SMapEntry_DoNotUse* internal_default_instance() { return reinterpret_cast<const SigMap_Pb_SMapEntry_DoNotUse*>(&_SigMap_Pb_SMapEntry_DoNotUse_default_instance_); }
static bool ValidateKey(std::string* s) {
return ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(s->data(), static_cast<int>(s->size()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::PARSE, "SigMap_Pb.SMapEntry.key");
}
static bool ValidateValue(void*) { return true; }
};
// -------------------------------------------------------------------
class SigMap_Pb final :
public ::PROTOBUF_NAMESPACE_ID::MessageLite /* @@protoc_insertion_point(class_definition:SigMap_Pb) */ {
public:
inline SigMap_Pb() : SigMap_Pb(nullptr) {}
~SigMap_Pb() override;
explicit constexpr SigMap_Pb(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
SigMap_Pb(const SigMap_Pb& from);
SigMap_Pb(SigMap_Pb&& from) noexcept
: SigMap_Pb() {
*this = ::std::move(from);
}
inline SigMap_Pb& operator=(const SigMap_Pb& from) {
CopyFrom(from);
return *this;
}
inline SigMap_Pb& operator=(SigMap_Pb&& from) noexcept {
if (this == &from) return *this;
if (GetOwningArena() == from.GetOwningArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
&& GetOwningArena() != nullptr
#endif // !PROTOBUF_FORCE_COPY_IN_MOVE
) {
InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
static const SigMap_Pb& default_instance() {
return *internal_default_instance();
}
static inline const SigMap_Pb* internal_default_instance() {
return reinterpret_cast<const SigMap_Pb*>(
&_SigMap_Pb_default_instance_);
}
static constexpr int kIndexInFileMessages =
1;
friend void swap(SigMap_Pb& a, SigMap_Pb& b) {
a.Swap(&b);
}
inline void Swap(SigMap_Pb* other) {
if (other == this) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
if (GetOwningArena() != nullptr &&
GetOwningArena() == other->GetOwningArena()) {
#else // PROTOBUF_FORCE_COPY_IN_SWAP
if (GetOwningArena() == other->GetOwningArena()) {
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(SigMap_Pb* other) {
if (other == this) return;
GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
InternalSwap(other);
}
// implements Message ----------------------------------------------
SigMap_Pb* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
return CreateMaybeMessage<SigMap_Pb>(arena);
}
void CheckTypeAndMergeFrom(const ::PROTOBUF_NAMESPACE_ID::MessageLite& from) final;
void CopyFrom(const SigMap_Pb& from);
void MergeFrom(const SigMap_Pb& from);
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
size_t ByteSizeLong() const final;
const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
uint8_t* _InternalSerialize(
uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(SigMap_Pb* other);
private:
friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
return "SigMap_Pb";
}
protected:
explicit SigMap_Pb(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
std::string GetTypeName() const final;
// nested types ----------------------------------------------------
// accessors -------------------------------------------------------
enum : int {
kSMapFieldNumber = 1,
};
// map<string, uint64> sMap = 1;
int smap_size() const;
private:
int _internal_smap_size() const;
public:
void clear_smap();
private:
const ::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >&
_internal_smap() const;
::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >*
_internal_mutable_smap();
public:
const ::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >&
smap() const;
::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >*
mutable_smap();
// @@protoc_insertion_point(class_scope:SigMap_Pb)
private:
class _Internal;
template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
::PROTOBUF_NAMESPACE_ID::internal::MapFieldLite<
SigMap_Pb_SMapEntry_DoNotUse,
std::string, uint64_t,
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING,
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_UINT64> smap_;
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
friend struct ::TableStruct_sig_5fmap_2eproto;
};
// ===================================================================
// ===================================================================
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif // __GNUC__
// -------------------------------------------------------------------
// SigMap_Pb
// map<string, uint64> sMap = 1;
inline int SigMap_Pb::_internal_smap_size() const {
return smap_.size();
}
inline int SigMap_Pb::smap_size() const {
return _internal_smap_size();
}
inline void SigMap_Pb::clear_smap() {
smap_.Clear();
}
inline const ::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >&
SigMap_Pb::_internal_smap() const {
return smap_.GetMap();
}
inline const ::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >&
SigMap_Pb::smap() const {
// @@protoc_insertion_point(field_map:SigMap_Pb.sMap)
return _internal_smap();
}
inline ::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >*
SigMap_Pb::_internal_mutable_smap() {
return smap_.MutableMap();
}
inline ::PROTOBUF_NAMESPACE_ID::Map< std::string, uint64_t >*
SigMap_Pb::mutable_smap() {
// @@protoc_insertion_point(field_mutable_map:SigMap_Pb.sMap)
return _internal_mutable_smap();
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif // __GNUC__
// -------------------------------------------------------------------
// @@protoc_insertion_point(namespace_scope)
// @@protoc_insertion_point(global_scope)
#include <thirdparty/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_sig_5fmap_2eproto

View File

@ -40,18 +40,16 @@ bool CIOStream::Open(const fs::path& fsFilePath, Mode_t eMode)
{
m_iStream.close();
}
m_iStream.open(fsFilePath, std::ios::binary | std::ios::in);
m_iStream.open(fsFilePath, std::ios::binary | std::ios::in || std::ios::ate);
if (!m_iStream.is_open() || !m_iStream.good())
{
m_eCurrentMode = Mode_t::NONE;
return false;
}
m_iStream.seekg(0, fstream::end);
m_vData.resize(m_iStream.tellg());
m_iStream.seekg(0, fstream::beg);
m_iStream.read(reinterpret_cast<char*>(m_vData.data()), m_vData.size());
m_iStream.seekg(0);
m_iStream.clear();
m_nSize = m_iStream.tellg();
m_iStream.seekg(0, std::ios::beg);
return true;
case Mode_t::WRITE:
@ -101,7 +99,7 @@ void CIOStream::Flush()
//-----------------------------------------------------------------------------
// Purpose: gets the position of the current character in the stream
//-----------------------------------------------------------------------------
size_t CIOStream::GetPosition()
std::streampos CIOStream::GetPosition()
{
switch (m_eCurrentMode)
{
@ -112,7 +110,7 @@ size_t CIOStream::GetPosition()
return m_oStream.tellp();
break;
default:
return static_cast<size_t>(NULL);
return static_cast<std::streampos>(NULL);
}
}
@ -120,7 +118,7 @@ size_t CIOStream::GetPosition()
// Purpose: sets the position of the current character in the stream
// Input : nOffset -
//-----------------------------------------------------------------------------
void CIOStream::SetPosition(int64_t nOffset)
void CIOStream::SetPosition(std::streampos nOffset)
{
switch (m_eCurrentMode)
{
@ -135,28 +133,20 @@ void CIOStream::SetPosition(int64_t nOffset)
}
}
//-----------------------------------------------------------------------------
// Purpose: returns the vector (ifstream only)
//-----------------------------------------------------------------------------
const vector<uint8_t>& CIOStream::GetVector() const
{
return m_vData;
}
//-----------------------------------------------------------------------------
// Purpose: returns the data (ifstream only)
//-----------------------------------------------------------------------------
const uint8_t* CIOStream::GetData() const
const std::filebuf* CIOStream::GetData() const
{
return m_vData.data();
return m_iStream.rdbuf();
}
//-----------------------------------------------------------------------------
// Purpose: returns the data size (ifstream only)
//-----------------------------------------------------------------------------
const size_t CIOStream::GetSize() const
const std::streampos CIOStream::GetSize() const
{
return m_vData.size();
return m_nSize;
}
//-----------------------------------------------------------------------------
@ -211,16 +201,18 @@ bool CIOStream::IsEof() const
//-----------------------------------------------------------------------------
string CIOStream::ReadString()
{
string result;
if (IsReadable())
{
char c;
string result = "";
while (!m_iStream.eof() && (c = Read<char>()) != '\0')
result += c;
return result;
}
return "";
return result;
}
//-----------------------------------------------------------------------------
@ -233,8 +225,8 @@ void CIOStream::WriteString(string svInput)
svInput += '\0'; // null-terminate the string.
char* szText = const_cast<char*>(svInput.c_str());
const char* szText = svInput.c_str();
size_t nSize = svInput.size();
m_oStream.write(reinterpret_cast<const char*>(szText), nSize);
m_oStream.write(szText, nSize);
}

View File

@ -18,12 +18,11 @@ public:
void Close();
void Flush();
size_t GetPosition();
void SetPosition(int64_t nOffset);
std::streampos GetPosition();
void SetPosition(std::streampos nOffset);
const vector<uint8_t>& GetVector() const;
const uint8_t* GetData() const;
const size_t GetSize() const;
const std::filebuf* GetData() const;
const std::streampos GetSize() const;
bool IsReadable();
bool IsWritable() const;
@ -34,7 +33,7 @@ public:
// Purpose: reads any value from the file
//-----------------------------------------------------------------------------
template<typename T>
void Read(T& tValue) // Template functions have to be in the header!
void Read(T& tValue)
{
if (IsReadable())
m_iStream.read(reinterpret_cast<char*>(&tValue), sizeof(tValue));
@ -44,7 +43,7 @@ public:
// Purpose: reads any value from the file with specified size
//-----------------------------------------------------------------------------
template<typename T>
void Read(T& tValue, size_t nSize) // Template functions have to be in the header!
void Read(T& tValue, size_t nSize)
{
if (IsReadable())
m_iStream.read(reinterpret_cast<char*>(&tValue), nSize);
@ -54,7 +53,7 @@ public:
// Purpose: reads any value from the file and returns it
//-----------------------------------------------------------------------------
template<typename T>
T Read() // Template functions have to be in the header!
T Read()
{
T value{};
if (!IsReadable())
@ -69,7 +68,7 @@ public:
// Purpose: writes any value to the file
//-----------------------------------------------------------------------------
template<typename T>
void Write(T tValue) // Template functions have to be in the header!
void Write(T tValue)
{
if (!IsWritable())
return;
@ -81,7 +80,7 @@ public:
// Purpose: writes any value to the file with specified size
//-----------------------------------------------------------------------------
template<typename T>
void Write(T tValue, size_t nSize) // Template functions have to be in the header!
void Write(T tValue, size_t nSize)
{
if (!IsWritable())
return;
@ -92,8 +91,8 @@ public:
private:
std::streampos m_nSize; // Size of ifstream.
Mode_t m_eCurrentMode; // Current active mode.
ofstream m_oStream; // Output file stream.
ifstream m_iStream; // Input file stream.
vector<uint8_t> m_vData; // Data vector
Mode_t m_eCurrentMode; // Current active mode.
};

View File

@ -46,6 +46,17 @@ CMemory CModule::FindPatternSIMD(const uint8_t* szPattern, const char* szMask, c
if (!m_ExecutableCode.IsSectionValid())
return CMemory();
//if (g_SigCache.m_bInitialized) // Get from cache instead.
//{
// auto p = g_SigCache.m_Map.find(szPattern);
// if (p != g_SigCache.m_Map.end())
// {
// return CMemory(p->second);
// }
//}
uint64_t nBase = static_cast<uint64_t>(m_ExecutableCode.m_pSectionBase);
uint64_t nSize = static_cast<uint64_t>(m_ExecutableCode.m_nSectionSize);
@ -55,12 +66,13 @@ CMemory CModule::FindPatternSIMD(const uint8_t* szPattern, const char* szMask, c
nSize = static_cast<uint64_t>(moduleSection.m_nSectionSize);
}
const size_t nMaskLen = strlen(szMask);
const uint8_t* pData = reinterpret_cast<uint8_t*>(nBase);
const uint8_t* pEnd = pData + static_cast<uint32_t>(nSize) - strlen(szMask);
const uint8_t* pEnd = pData + static_cast<uint32_t>(nSize) - nMaskLen;
int nOccurrenceCount = 0;
int nMasks[64]; // 64*16 = enough masks for 1024 bytes.
const int iNumMasks = static_cast<int>(ceil(static_cast<float>(strlen(szMask)) / 16.f));
const int iNumMasks = static_cast<int>(ceil(static_cast<float>(nMaskLen) / 16.f));
memset(nMasks, '\0', iNumMasks * sizeof(int));
for (intptr_t i = 0; i < iNumMasks; ++i)
@ -94,6 +106,7 @@ CMemory CModule::FindPatternSIMD(const uint8_t* szPattern, const char* szMask, c
{
if (nOccurrenceCount == nOccurrence)
{
g_SigCache.AddEntry(reinterpret_cast<const char*>(szPattern), nMaskLen, reinterpret_cast<uint64_t>(pData - nBase));
return static_cast<CMemory>(const_cast<uint8_t*>(pData));
}
nOccurrenceCount++;
@ -106,6 +119,7 @@ CMemory CModule::FindPatternSIMD(const uint8_t* szPattern, const char* szMask, c
}
if (nOccurrenceCount == nOccurrence)
{
g_SigCache.AddEntry(reinterpret_cast<const char*>(szPattern), nMaskLen, reinterpret_cast<uint64_t>(pData - nBase));
return static_cast<CMemory>((&*(const_cast<uint8_t*>(pData))));
}
nOccurrenceCount++;

View File

@ -0,0 +1,37 @@
//===========================================================================//
//
// Purpose: Implementation of the CSigCache class.
//
//===========================================================================//
#include "core/stdafx.h"
#include "public/utility/binstream.h"
#include "sigcache.h"
void CSigCache::AddEntry(const char* pszPattern, const size_t nMaskLen, const uint64_t nRVA)
{
if (g_SigCache.m_bUseCache)
{
(*g_SigCache.m_Cache.mutable_smap())[string(pszPattern, nMaskLen)] = nRVA;
}
}
void CSigCache::WriteCache()
{
CIOStream writer("bin\\startup.smap", CIOStream::Mode_t::WRITE);
if (!writer.IsWritable())
{
// Error message..
return;
}
SigDBHeader_t header;
header.m_nMagic = SIGDB_MAGIC;
header.m_nVersion = SIGDB_VERSION;
GetSystemTimeAsFileTime(&header.m_FileTime);
const string svBuffer = m_Cache.SerializeAsString();
writer.Write(header);
writer.Write(svBuffer.data(), svBuffer.size());
}

View File

@ -0,0 +1,32 @@
#ifndef SIGCACHE_H
#define SIGCACHE_H
#include "protoc/sig_map.pb.h"
#define SIGDB_MAGIC (('p'<<24)+('a'<<16)+('M'<<8)+'S')
#define SIGDB_VERSION 0x1
class CSigCache
{
public:
// Save
// Load
// Clear
void AddEntry(const char* pszPattern, const size_t nMaskLen, const uint64_t nRVA);
void WriteCache();
SigMap_Pb m_Cache;
bool m_bInitialized;
bool m_bUseCache = true;
};
struct SigDBHeader_t
{
int m_nMagic;
int m_nVersion;
FILETIME m_FileTime;
};
#endif // !SIGCACHE_H

View File

@ -0,0 +1,7 @@
syntax = "proto3";
option optimize_for = LITE_RUNTIME;
message SigMap_Pb
{
map<string,uint64> sMap = 1;
}

View File

@ -99,6 +99,10 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\protoc\sig_map.pb.cc">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\protoc\sv_rcon.pb.cc">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
@ -107,6 +111,7 @@
<ClCompile Include="..\public\utility\binstream.cpp" />
<ClCompile Include="..\public\utility\memaddr.cpp" />
<ClCompile Include="..\public\utility\module.cpp" />
<ClCompile Include="..\public\utility\sigcache.cpp" />
<ClCompile Include="..\public\utility\utility.cpp" />
<ClCompile Include="..\rtech\rtech_utils.cpp" />
<ClCompile Include="..\rtech\rtech_game.cpp" />
@ -281,6 +286,7 @@
<ClInclude Include="..\pluginsystem\ipluginsystem.h" />
<ClInclude Include="..\pluginsystem\pluginsystem.h" />
<ClInclude Include="..\protoc\cl_rcon.pb.h" />
<ClInclude Include="..\protoc\sig_map.pb.h" />
<ClInclude Include="..\protoc\sv_rcon.pb.h" />
<ClInclude Include="..\public\avi\iavi.h" />
<ClInclude Include="..\public\avi\ibik.h" />
@ -329,6 +335,7 @@
<ClInclude Include="..\public\utility\httplib.h" />
<ClInclude Include="..\public\utility\memaddr.h" />
<ClInclude Include="..\public\utility\module.h" />
<ClInclude Include="..\public\utility\sigcache.h" />
<ClInclude Include="..\public\utility\utility.h" />
<ClInclude Include="..\public\worldsize.h" />
<ClInclude Include="..\rtech\rtech_utils.h" />
@ -593,6 +600,7 @@
</ItemGroup>
<ItemGroup>
<None Include="..\GameSDK.def" />
<None Include="..\protoc\sig_map.pb.cc.vsspell" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>

View File

@ -672,6 +672,12 @@
<ClCompile Include="..\codecs\Miles\miles_impl.cpp">
<Filter>sdk\codecs\miles</Filter>
</ClCompile>
<ClCompile Include="..\protoc\sig_map.pb.cc">
<Filter>thirdparty\protobuf</Filter>
</ClCompile>
<ClCompile Include="..\public\utility\sigcache.cpp">
<Filter>sdk\public\utility</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\client\cdll_engine_int.h">
@ -1937,6 +1943,12 @@
<ClInclude Include="..\codecs\Miles\miles_types.h">
<Filter>sdk\codecs\miles</Filter>
</ClInclude>
<ClInclude Include="..\protoc\sig_map.pb.h">
<Filter>thirdparty\protobuf</Filter>
</ClInclude>
<ClInclude Include="..\public\utility\sigcache.h">
<Filter>sdk\public\utility</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="..\shared\resource\lockedserver.png">
@ -1950,5 +1962,6 @@
</ItemGroup>
<ItemGroup>
<None Include="..\GameSDK.def" />
<None Include="..\protoc\sig_map.pb.cc.vsspell" />
</ItemGroup>
</Project>