Skip to content

Commit f09f376

Browse files
committed
Update CModule & CMemory things
1 parent 7e96253 commit f09f376

6 files changed

Lines changed: 70 additions & 67 deletions

File tree

include/dynlibutils/memaddr.hpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ class CMemory
9090
public:
9191
// Constructor ones.
9292
constexpr CMemory(const CMemory&) noexcept = default;
93+
constexpr CMemory(CMemory&&) noexcept = default;
9394
constexpr CMemory& operator=(const CMemory&) noexcept = default;
94-
constexpr CMemory(CMemory&& other) noexcept : m_addr(std::move(other.m_addr)) {}
95+
constexpr CMemory& operator=(CMemory&& other) noexcept = default;
9596
constexpr CMemory(const std::uintptr_t addr) : m_addr(addr) {}
9697
constexpr CMemory(void* ptr = nullptr) : m_ptr(ptr) {}
9798

@@ -117,12 +118,17 @@ class CMemory
117118
template<typename PTR> constexpr PTR RCast() const noexcept { return reinterpret_cast<PTR>(m_addr); }
118119
template<typename PTR> constexpr PTR UCast() const noexcept { union { PTR cptr; std::uintptr_t addr; } cast; cast.addr = m_addr; return cast.cptr; }
119120

120-
/// Access methods.
121+
/// Access methods (getters).
121122
constexpr void* GetPtr() const noexcept { return m_ptr; }
122123
constexpr std::ptrdiff_t GetAddr() const noexcept { return m_addr; }
123124
template<typename T> constexpr T &GetRef() const noexcept { return *RCast<T*>(); }
124125
template<typename T> constexpr T Get() const { return GetRef<T>(); }
125126

127+
/// Access methods (setters).
128+
constexpr void* SetPtr(void* pNew) noexcept { return m_ptr = pNew; }
129+
constexpr std::ptrdiff_t SetAddr(std::ptrdiff_t nNew) noexcept { return m_addr = nNew; }
130+
template<typename T> constexpr T &Set(const T &other) noexcept { return &GetRef<T>() = other; }
131+
126132
// Checks methods.
127133
bool IsValid() const noexcept { return GetPtr() != nullptr; }
128134

@@ -131,7 +137,7 @@ class CMemory
131137
CMemory& OffsetSelf(const std::ptrdiff_t offset) noexcept { m_addr += offset; return *this; }
132138

133139
// Multi-level dereferencing methods.
134-
CMemory Deref(std::uintptr_t deref = 1, std::ptrdiff_t offset = 0) const
140+
CMemory Deref(std::uintptr_t deref = 1, std::ptrdiff_t offset = 0) const noexcept
135141
{
136142
std::uintptr_t base = m_addr;
137143

@@ -142,20 +148,20 @@ class CMemory
142148

143149
return base;
144150
}
145-
CMemory& DerefSelf(int deref = 1, std::ptrdiff_t offset = 0) { while (m_addr && deref--) m_addr = *reinterpret_cast<std::uintptr_t*>(m_addr + offset); return *this; }
151+
CMemory& DerefSelf(int deref = 1, std::ptrdiff_t offset = 0) noexcept { while (m_addr && deref--) m_addr = *reinterpret_cast<std::uintptr_t*>(m_addr + offset); return *this; }
146152

147-
CMemory FollowNearCall(const std::ptrdiff_t opcodeOffset = 0x1, const std::ptrdiff_t nextInstructionOffset = 0x5) const { return ResolveRelativeAddress(opcodeOffset, nextInstructionOffset); }
148-
CMemory& FollowNearCallSelf(const std::ptrdiff_t opcodeOffset = 0x1, const std::ptrdiff_t nextInstructionOffset = 0x5) { return ResolveRelativeAddressSelf(opcodeOffset, nextInstructionOffset); }
153+
CMemory FollowNearCall(const std::ptrdiff_t opcodeOffset = 0x1, const std::ptrdiff_t nextInstructionOffset = 0x5) const noexcept { return ResolveRelativeAddress(opcodeOffset, nextInstructionOffset); }
154+
CMemory& FollowNearCallSelf(const std::ptrdiff_t opcodeOffset = 0x1, const std::ptrdiff_t nextInstructionOffset = 0x5) noexcept { return ResolveRelativeAddressSelf(opcodeOffset, nextInstructionOffset); }
149155

150-
CMemory ResolveRelativeAddress(const std::ptrdiff_t registerOffset = 0x0, const std::ptrdiff_t nextInstructionOffset = 0x4) const
156+
CMemory ResolveRelativeAddress(const std::ptrdiff_t registerOffset = 0x0, const std::ptrdiff_t nextInstructionOffset = 0x4) const noexcept
151157
{
152158
const std::uintptr_t skipRegister = m_addr + registerOffset;
153159
const std::uintptr_t nextInstruction = m_addr + nextInstructionOffset;
154160
const std::int32_t relativeAddress = *reinterpret_cast<std::int32_t*>(skipRegister);
155161

156162
return nextInstruction + relativeAddress;
157163
}
158-
CMemory& ResolveRelativeAddressSelf(const std::ptrdiff_t registerOffset = 0x0, const std::ptrdiff_t nextInstructionOffset = 0x4)
164+
CMemory& ResolveRelativeAddressSelf(const std::ptrdiff_t registerOffset = 0x0, const std::ptrdiff_t nextInstructionOffset = 0x4) noexcept
159165
{
160166
const std::uintptr_t skipRegister = m_addr + registerOffset;
161167
const std::uintptr_t nextInstruction = m_addr + nextInstructionOffset;
@@ -246,8 +252,6 @@ class CMemoryView : public CMemory
246252
CMemory operator+(const CMemory right) const noexcept { return Offset(static_cast<std::ptrdiff_t>(right.GetAddr())); }
247253
CMemory operator-(const CMemory right) const noexcept { return Offset(static_cast<std::ptrdiff_t>(right.GetAddr())); }
248254

249-
using CMemory::IsValid;
250-
251255
/// Cast methods (view ones).
252256
constexpr T* CCastView() const noexcept { return CBase::CCast<T*>(); }
253257
constexpr T* RCastView() const noexcept { return CBase::RCast<T*>(); }

include/dynlibutils/module.hpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,8 @@ inline auto ParsePattern(const std::string_view svInput)
237237
return result;
238238
}
239239

240-
class CModule
240+
class CModule : public CMemory
241241
{
242-
private:
243-
std::string m_sPath;
244-
std::string m_sLastError;
245-
std::vector<Section_t> m_vecSections;
246-
const Section_t *m_pExecutableSection;
247-
void* m_pHandle;
248-
249242
public:
250243
template<std::size_t SIZE>
251244
class CSignatureView : public Pattern_t<SIZE>
@@ -261,6 +254,8 @@ class CModule
261254
constexpr CSignatureView(const Base_t& pattern, CModule* module) : Base_t(pattern), m_pModule(module) {}
262255
constexpr CSignatureView(Base_t&& pattern, CModule* module) : Base_t(std::move(pattern)), m_pModule(module) {}
263256

257+
bool IsValid() const { return m_pModule && m_pModule->IsValid(); }
258+
264259
[[nodiscard]]
265260
CMemory operator()(const CMemory pStart = nullptr, const Section_t* pSection = nullptr) const
266261
{
@@ -274,14 +269,22 @@ class CModule
274269
[[nodiscard]] CMemory OffsetAndFind(const std::ptrdiff_t offset, CMemory pStart, const Section_t* pSection = nullptr) const { return Find(pStart + offset, pSection); }
275270
[[nodiscard]] CMemory OffsetFromSelfAndFind(const CMemory pStart, const Section_t* pSection = nullptr) const { return OffsetAndFind(Base_t::m_nSize, pStart, pSection); }
276271
[[nodiscard]] CMemory DerefAndFind(const std::uintptr_t deref, CMemory pStart, const Section_t* pSection = nullptr) const { return Find(pStart.Deref(deref), pSection); }
277-
}; // struct CSignatureView
272+
}; // class CSignatureView<SIZE>
278273

279-
CModule() : m_pExecutableSection(nullptr), m_pHandle(nullptr) {}
274+
private:
275+
std::string m_sPath;
276+
std::string m_sLastError;
277+
std::vector<Section_t> m_vecSections;
278+
279+
const Section_t *m_pExecutableSection;
280+
281+
public:
282+
CModule() : m_pExecutableSection(nullptr) {}
280283
~CModule();
281284

282285
CModule(const CModule&) = delete;
283286
CModule& operator=(const CModule&) = delete;
284-
CModule(CModule&& other) noexcept : m_sPath(std::move(other.m_sPath)), m_vecSections(std::move(other.m_vecSections)), m_pExecutableSection(std::move(other.m_pExecutableSection)), m_pHandle(std::move(other.m_pHandle)) {}
287+
CModule(CModule&& other) noexcept = default;
285288
CModule(const CMemory pModuleMemory);
286289
explicit CModule(const std::string_view svModuleName);
287290
explicit CModule(const char* pszModuleName) : CModule(std::string_view(pszModuleName)) {}
@@ -466,7 +469,7 @@ class CModule
466469
[[nodiscard]] CMemory GetVirtualTableByName(const std::string_view svTableName, bool bDecorated = false) const;
467470
[[nodiscard]] CMemory GetFunctionByName(const std::string_view svFunctionName) const noexcept;
468471

469-
[[nodiscard]] void* GetHandle() const noexcept { return m_pHandle; }
472+
[[nodiscard]] void* GetHandle() const noexcept { return GetPtr(); }
470473
[[nodiscard]] CMemory GetBase() const noexcept;
471474
[[nodiscard]] std::string_view GetPath() const { return m_sPath; }
472475
[[nodiscard]] std::string_view GetLastError() const { return m_sLastError; }
@@ -484,6 +487,13 @@ class CModule
484487
void SaveLastError();
485488
}; // class CModule
486489

490+
class Module final : CModule
491+
{
492+
public:
493+
using CBase = CModule;
494+
using CBase::CBase;
495+
};
496+
487497
} // namespace DynLibUtils
488498

489499
#endif // DYNLIBUTILS_MODULE_HPP

src/apple/module.cpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ using namespace DynLibUtils;
4040

4141
CModule::~CModule()
4242
{
43-
if (m_pHandle)
44-
dlclose(m_pHandle);
43+
if (IsValid())
44+
dlclose(GetPtr());
4545
}
4646

4747
//-----------------------------------------------------------------------------
@@ -52,7 +52,7 @@ CModule::~CModule()
5252
//-----------------------------------------------------------------------------
5353
bool CModule::InitFromName(const std::string_view svModuleName, bool bExtension)
5454
{
55-
if (m_pHandle)
55+
if (IsValid())
5656
return false;
5757

5858
if (svModuleName.empty())
@@ -63,9 +63,9 @@ bool CModule::InitFromName(const std::string_view svModuleName, bool bExtension)
6363
if (!bExtension)
6464
sModuleName.append(".dylib");
6565

66-
m_pHandle = dlopen(sModuleName.c_str(), RTLD_LAZY);
66+
SetPtr(dlopen(sModuleName.c_str(), RTLD_LAZY));
6767

68-
return (m_pHandle != nullptr);
68+
return IsValid();
6969
}
7070

7171
//-----------------------------------------------------------------------------
@@ -75,10 +75,10 @@ bool CModule::InitFromName(const std::string_view svModuleName, bool bExtension)
7575
//-----------------------------------------------------------------------------
7676
bool CModule::InitFromMemory(const CMemory pModuleMemory, bool bForce)
7777
{
78-
if (!pModuleMemory.IsValid())
79-
return DYNLIB_INVALID_MEMORY;
78+
if (IsValid() && !bForce)
79+
return false;
8080

81-
if (!bForce && m_pHandle)
81+
if (!pModuleMemory.IsValid())
8282
return false;
8383

8484
Dl_info info;
@@ -102,13 +102,13 @@ bool CModule::LoadFromPath(const std::string_view svModelePath, int flags)
102102
return false;
103103
}
104104

105-
m_pHandle = handle;
105+
SetPtr(handle);
106106
m_sPath = std::move(svModelePath);
107107

108108
if (m_vecSections.size())
109109
return true;
110110

111-
const MachHeader* header = reinterpret_cast<const MachHeader*>(m_pHandle);
111+
const auto* header = RCast<const MachHeader*>();
112112

113113
/*
114114
if (header->magic != MACH_MAGIC) {
@@ -138,7 +138,7 @@ bool CModule::LoadFromPath(const std::string_view svModelePath, int flags)
138138
m_vecSections.emplace_back(
139139
section.size,
140140
section.sectname,
141-
reinterpret_cast<uintptr_t>(m_pHandle) + section.addr
141+
GetAddr() + section.addr
142142
);
143143
}
144144
}
@@ -174,18 +174,15 @@ CMemory CModule::GetVirtualTableByName(const std::string_view svTableName, bool
174174
//-----------------------------------------------------------------------------
175175
CMemory CModule::GetFunctionByName(const std::string_view svFunctionName) const noexcept
176176
{
177-
assert(!svFunctionName.empty());
178-
assert(m_pHandle != nullptr);
179-
180-
return m_pHandle ? DynLibUtils::CMemory(dlsym(m_pHandle, svFunctionName.data())) : DYNLIB_INVALID_MEMORY;
177+
return CMemory((IsValid() && !svFunctionName.empty()) ? dlsym(GetPtr(), svFunctionName.data()) : nullptr);
181178
}
182179

183180
//-----------------------------------------------------------------------------
184181
// Purpose: Returns the module base
185182
//-----------------------------------------------------------------------------
186183
CMemory CModule::GetBase() const noexcept
187184
{
188-
return static_cast<dlopen_handle*>(m_pHandle)->module;
185+
return CMemory(RCast<dlopen_handle*>()->module);
189186
}
190187

191188
void CModule::SaveLastError()

src/linux/module.cpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ using namespace DynLibUtils;
1616

1717
CModule::~CModule()
1818
{
19-
if (m_pHandle)
20-
dlclose(m_pHandle);
19+
if (IsValid())
20+
dlclose(GetPtr());
2121
}
2222

2323
//-----------------------------------------------------------------------------
@@ -28,7 +28,7 @@ CModule::~CModule()
2828
//-----------------------------------------------------------------------------
2929
bool CModule::InitFromName(const std::string_view svModuleName, bool bExtension)
3030
{
31-
if (m_pHandle)
31+
if (IsValid())
3232
return false;
3333

3434
if (svModuleName.empty())
@@ -74,12 +74,10 @@ bool CModule::InitFromName(const std::string_view svModuleName, bool bExtension)
7474
//-----------------------------------------------------------------------------
7575
bool CModule::InitFromMemory(const CMemory pModuleMemory, bool bForce)
7676
{
77-
assert(pModuleMemory.IsValid());
78-
79-
if (!pModuleMemory.IsValid())
77+
if (IsValid() && !bForce)
8078
return false;
8179

82-
if (!bForce && m_pHandle)
80+
if (!pModuleMemory.IsValid())
8381
return false;
8482

8583
Dl_info info;
@@ -143,7 +141,7 @@ bool CModule::LoadFromPath(const std::string_view svModelePath, int flags)
143141

144142
close(fd);
145143

146-
m_pHandle = handle;
144+
SetPtr(handle);
147145
m_sPath.assign(svModelePath);
148146

149147
m_pExecutableSection = GetSectionByName(".text");
@@ -211,18 +209,15 @@ CMemory CModule::GetVirtualTableByName(const std::string_view svTableName, bool
211209
//-----------------------------------------------------------------------------
212210
CMemory CModule::GetFunctionByName(const std::string_view svFunctionName) const noexcept
213211
{
214-
assert(!svFunctionName.empty());
215-
assert(m_pHandle != nullptr);
216-
217-
return m_pHandle ? DynLibUtils::CMemory(dlsym(m_pHandle, svFunctionName.data())) : DYNLIB_INVALID_MEMORY;
212+
return CMemory((IsValid() && !svFunctionName.empty()) ? dlsym(GetPtr(), svFunctionName.data()) : nullptr);
218213
}
219214

220215
//-----------------------------------------------------------------------------
221216
// Purpose: Returns the module base
222217
//-----------------------------------------------------------------------------
223218
CMemory CModule::GetBase() const noexcept
224219
{
225-
return static_cast<link_map*>(m_pHandle)->l_addr;
220+
return RCast<link_map*>()->l_addr;
226221
}
227222

228223
void CModule::SaveLastError()

src/module.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ using namespace DynLibUtils;
1515
// Purpose: constructor
1616
// Input : szModuleName (without extension .dll/.so)
1717
//-----------------------------------------------------------------------------
18-
CModule::CModule(const std::string_view szModuleName) : m_pHandle(nullptr)
18+
CModule::CModule(const std::string_view szModuleName)
1919
{
2020
InitFromName(szModuleName);
2121
}
@@ -24,7 +24,7 @@ CModule::CModule(const std::string_view szModuleName) : m_pHandle(nullptr)
2424
// Purpose: constructor
2525
// Input : pModuleMemory
2626
//-----------------------------------------------------------------------------
27-
CModule::CModule(const CMemory pModuleMemory) : m_pHandle(nullptr)
27+
CModule::CModule(const CMemory pModuleMemory)
2828
{
2929
InitFromMemory(pModuleMemory);
3030
}

src/windows/module.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ namespace DynLibUtils {
1616

1717
CModule::~CModule()
1818
{
19-
if (m_pHandle)
20-
FreeLibrary(reinterpret_cast<HMODULE>(m_pHandle));
19+
if (IsValid())
20+
FreeLibrary(RCast<HMODULE>());
2121
}
2222

2323
static std::string GetModulePath(HMODULE hModule)
@@ -52,9 +52,10 @@ static std::string GetModulePath(HMODULE hModule)
5252
//-----------------------------------------------------------------------------
5353
bool CModule::InitFromName(const std::string_view svModuleName, bool bExtension)
5454
{
55-
assert(!svModuleName.empty());
55+
if (IsValid())
56+
return false;
5657

57-
if (m_pHandle)
58+
if (!svModuleName.empty())
5859
return false;
5960

6061
std::string sModuleName(svModuleName);
@@ -82,9 +83,10 @@ bool CModule::InitFromName(const std::string_view svModuleName, bool bExtension)
8283
//-----------------------------------------------------------------------------
8384
bool CModule::InitFromMemory(const CMemory pModuleMemory, bool bForce)
8485
{
85-
assert(pModuleMemory.IsValid());
86+
if (IsValid() && !bForce)
87+
return false;
8688

87-
if (!bForce && m_pHandle)
89+
if (!pModuleMemory.IsValid())
8890
return false;
8991

9092
MEMORY_BASIC_INFORMATION mbi;
@@ -124,7 +126,7 @@ bool CModule::LoadFromPath(const std::string_view svModelePath, int flags)
124126
m_vecSections.emplace_back(hCurrentSection.SizeOfRawData, reinterpret_cast<const char*>(hCurrentSection.Name), static_cast<uintptr_t>(reinterpret_cast<uintptr_t>(handle) + hCurrentSection.VirtualAddress)); // Push back a struct with the section data.
125127
}
126128

127-
m_pHandle = handle;
129+
SetPtr(static_cast<void *>(handle));
128130
m_sPath.assign(svModelePath);
129131

130132
m_pExecutableSection = GetSectionByName(".text");
@@ -184,20 +186,15 @@ CMemory CModule::GetVirtualTableByName(const std::string_view svTableName, bool
184186
//-----------------------------------------------------------------------------
185187
CMemory CModule::GetFunctionByName(const std::string_view svFunctionName) const noexcept
186188
{
187-
assert(!svFunctionName.empty());
188-
189-
if(!m_pHandle)
190-
return DYNLIB_INVALID_MEMORY;
191-
192-
return GetProcAddress(reinterpret_cast<HMODULE>(m_pHandle), svFunctionName.data());
189+
return CMemory((IsValid() && !svFunctionName.empty()) ? GetProcAddress(static_cast<HMODULE>(GetPtr()), svFunctionName.data()) : nullptr);
193190
}
194191

195192
//-----------------------------------------------------------------------------
196193
// Purpose: Returns the module base
197194
//-----------------------------------------------------------------------------
198195
CMemory CModule::GetBase() const noexcept
199196
{
200-
return m_pHandle;
197+
return *this;
201198
}
202199

203200
void CModule::SaveLastError()

0 commit comments

Comments
 (0)