Skip to content

Commit 4db2015

Browse files
committed
Fixed crashes due to the last update when searching for a symbol on Linux
1 parent 9a92f4c commit 4db2015

File tree

3 files changed

+41
-32
lines changed

3 files changed

+41
-32
lines changed

src/core/modules/memory/memory_scanner.cpp

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,10 @@ extern IVEngineServer* engine;
5656
//-----------------------------------------------------------------------------
5757
// BinaryFile class
5858
//-----------------------------------------------------------------------------
59-
CBinaryFile::CBinaryFile(unsigned long ulAddr, unsigned long ulSize)
59+
CBinaryFile::CBinaryFile(unsigned long ulModule, unsigned long ulBase, unsigned long ulSize)
6060
{
61-
m_ulAddr = ulAddr;
61+
m_ulModule = ulModule;
62+
m_ulBase = ulBase;
6263
m_ulSize = ulSize;
6364
}
6465

@@ -70,7 +71,7 @@ CPointer* CBinaryFile::FindSignatureRaw(object oSignature)
7071

7172
int iLength = len(oSignature);
7273

73-
unsigned char* base = (unsigned char *) m_ulAddr;
74+
unsigned char* base = (unsigned char *) m_ulBase;
7475
unsigned char* end = (unsigned char *) (base + m_ulSize - iLength);
7576

7677
while(base < end)
@@ -151,7 +152,7 @@ bool CBinaryFile::SearchSigHooked(object oSignature, int iLength, unsigned char*
151152
CPointer new_ptr = CPointer(pPtr->m_ulAddr + len(oSignature));
152153

153154
// Got another match after the first one?
154-
CPointer* pNext = new_ptr.SearchBytes(oSignature, (m_ulAddr + m_ulSize) - new_ptr.m_ulAddr);
155+
CPointer* pNext = new_ptr.SearchBytes(oSignature, (m_ulBase + m_ulSize) - new_ptr.m_ulAddr);
155156
bool bIsValid = pNext->IsValid();
156157
delete pNext;
157158

@@ -201,10 +202,10 @@ CPointer* CBinaryFile::FindSignature(object oSignature)
201202
CPointer* CBinaryFile::FindSymbol(char* szSymbol)
202203
{
203204
#ifdef _WIN32
204-
return new CPointer((unsigned long) GetProcAddress((HMODULE) m_ulAddr, szSymbol));
205+
return new CPointer((unsigned long) GetProcAddress((HMODULE) m_ulModule, szSymbol));
205206

206207
#elif defined(__linux__)
207-
void* pResult = dlsym((void*) m_ulAddr, szSymbol);
208+
void* pResult = dlsym((void*) m_ulModule, szSymbol);
208209
if (pResult)
209210
return new CPointer((unsigned long) pResult);
210211

@@ -227,7 +228,7 @@ CPointer* CBinaryFile::FindSymbol(char* szSymbol)
227228
uint16_t section_count;
228229
uint32_t symbol_count;
229230

230-
dlmap = (struct link_map *) m_ulAddr;
231+
dlmap = (struct link_map *) m_ulModule;
231232
symtab_hdr = NULL;
232233
strtab_hdr = NULL;
233234

@@ -339,31 +340,31 @@ dict CBinaryFile::GetSymbols()
339340
{
340341
dict result;
341342
#ifdef _WIN32
342-
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER) m_ulAddr;
343+
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER) m_ulModule;
343344
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
344345
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Unable to retrieve DOS header.")
345346

346-
PIMAGE_NT_HEADERS nt_headers = (PIMAGE_NT_HEADERS) ((BYTE *) m_ulAddr + dos_header->e_lfanew);
347+
PIMAGE_NT_HEADERS nt_headers = (PIMAGE_NT_HEADERS) ((BYTE *) m_ulModule + dos_header->e_lfanew);
347348
if (nt_headers->Signature != IMAGE_NT_SIGNATURE)
348349
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Unable to retrieve NT headers.")
349350

350351
if (nt_headers->OptionalHeader.NumberOfRvaAndSizes <= 0)
351352
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Invalid number of directories in the optional header.")
352353

353354
PIMAGE_EXPORT_DIRECTORY exports = (PIMAGE_EXPORT_DIRECTORY) (
354-
(BYTE *) m_ulAddr
355+
(BYTE *) m_ulModule
355356
+ nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
356357

357358
if (exports->AddressOfNames == NULL)
358359
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Address of names is NULL.")
359360

360-
BYTE** symbols = (BYTE**)(m_ulAddr + exports->AddressOfNames);
361+
BYTE** symbols = (BYTE**)(m_ulModule + exports->AddressOfNames);
361362
for (DWORD i=0; i < exports->NumberOfNames; i++)
362363
{
363-
const char* name = (const char*) (m_ulAddr + symbols[i]);
364+
const char* name = (const char*) (m_ulModule + symbols[i]);
364365

365366
// TODO: Don't use GetProcAddress. There is probably a faster way
366-
result[name] = CPointer((unsigned long) GetProcAddress((HMODULE) m_ulAddr, name));
367+
result[name] = CPointer((unsigned long) GetProcAddress((HMODULE) m_ulModule, name));
367368
}
368369
#elif __linux__
369370
// TODO: Remove duplicated code. See also: FindSymbol()
@@ -379,7 +380,7 @@ dict CBinaryFile::GetSymbols()
379380
uint16_t section_count;
380381
uint32_t symbol_count;
381382

382-
dlmap = (struct link_map *) m_ulAddr;
383+
dlmap = (struct link_map *) m_ulModule;
383384
symtab_hdr = NULL;
384385
strtab_hdr = NULL;
385386

@@ -482,21 +483,22 @@ CBinaryFile* CBinaryManager::FindBinary(char* szPath, bool bSrvCheck /* = true *
482483
}
483484
#endif
484485

485-
unsigned long ulAddr = (unsigned long) dlLoadLibrary(szBinaryPath.data());
486+
unsigned long ulModule = (unsigned long) dlLoadLibrary(szBinaryPath.data());
487+
unsigned long ulBase = 0;
486488
#ifdef __linux__
487-
if (!ulAddr)
489+
if (!ulModule)
488490
{
489491
char szGameDir[MAX_PATH_LENGTH];
490492
engine->GetGameDir(szGameDir, MAX_PATH_LENGTH);
491493

492494
// If the previous path failed, try the "bin" folder of the game.
493495
// This will allow passing e.g. "server" to this function.
494496
szBinaryPath = std::string(szGameDir) + "/bin/" + szBinaryPath;
495-
ulAddr = (unsigned long) dlLoadLibrary(szBinaryPath.data());
497+
ulModule = (unsigned long) dlLoadLibrary(szBinaryPath.data());
496498
}
497499
#endif
498500

499-
if (!ulAddr)
501+
if (!ulModule)
500502
{
501503
szBinaryPath = "Unable to find " + szBinaryPath;
502504
#ifdef _WIN32
@@ -510,20 +512,21 @@ CBinaryFile* CBinaryManager::FindBinary(char* szPath, bool bSrvCheck /* = true *
510512
for (std::list<CBinaryFile *>::iterator iter=m_Binaries.begin(); iter != m_Binaries.end(); ++iter)
511513
{
512514
CBinaryFile* binary = *iter;
513-
if (binary->m_ulAddr == ulAddr)
515+
if (binary->m_ulModule == ulModule)
514516
{
515517
// We don't need to open it several times
516-
dlFreeLibrary((DLLib *) ulAddr);
518+
dlFreeLibrary((DLLib *) ulModule);
517519
return binary;
518520
}
519521
}
520522

521523
unsigned long ulSize;
522524

523525
#ifdef _WIN32
524-
IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER *) ulAddr;
526+
IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER *) ulModule;
525527
IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS *) ((BYTE *) dos + dos->e_lfanew);
526528
ulSize = nt->OptionalHeader.SizeOfImage;
529+
ulBase = ulModule;
527530

528531
#elif defined(__linux__)
529532
// Copied from here. Thanks!
@@ -533,9 +536,9 @@ CBinaryFile* CBinaryManager::FindBinary(char* szPath, bool bSrvCheck /* = true *
533536
Elf32_Phdr *phdr;
534537
uint16_t phdrCount;
535538

536-
struct link_map *lm = (struct link_map*) ulAddr;
537-
ulAddr = reinterpret_cast<uintptr_t>(lm->l_addr);
538-
file = reinterpret_cast<Elf32_Ehdr *>(ulAddr);
539+
struct link_map *lm = (struct link_map*) ulModule;
540+
ulBase = reinterpret_cast<uintptr_t>(lm->l_addr);
541+
file = reinterpret_cast<Elf32_Ehdr *>(ulBase);
539542

540543
/* Check ELF magic */
541544
if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0)
@@ -564,7 +567,7 @@ CBinaryFile* CBinaryManager::FindBinary(char* szPath, bool bSrvCheck /* = true *
564567
}
565568

566569
phdrCount = file->e_phnum;
567-
phdr = reinterpret_cast<Elf32_Phdr *>(ulAddr + file->e_phoff);
570+
phdr = reinterpret_cast<Elf32_Phdr *>(ulBase + file->e_phoff);
568571

569572
for (uint16_t i = 0; i < phdrCount; i++)
570573
{
@@ -589,7 +592,7 @@ CBinaryFile* CBinaryManager::FindBinary(char* szPath, bool bSrvCheck /* = true *
589592
#endif
590593

591594
// Create a new Binary object and add it to the list
592-
CBinaryFile* binary = new CBinaryFile(ulAddr, ulSize);
595+
CBinaryFile* binary = new CBinaryFile(ulModule, ulBase, ulSize);
593596
m_Binaries.push_front(binary);
594597
return binary;
595598
}

src/core/modules/memory/memory_scanner.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct Signature_t
4444
class CBinaryFile
4545
{
4646
public:
47-
CBinaryFile(unsigned long ulAddr, unsigned long ulSize);
47+
CBinaryFile(unsigned long ulModule, unsigned long ulBase, unsigned long ulSize);
4848

4949
CPointer* FindSignatureRaw(object oSignature);
5050

@@ -63,9 +63,10 @@ class CBinaryFile
6363
bool SearchSigHooked(object oSignature, int iLength, unsigned char* sigstr, CPointer*& result);
6464

6565
public:
66-
unsigned long m_ulAddr;
67-
unsigned long m_ulSize;
68-
std::list<Signature_t> m_Signatures;
66+
unsigned long m_ulModule;
67+
unsigned long m_ulBase;
68+
unsigned long m_ulSize;
69+
std::list<Signature_t> m_Signatures;
6970
};
7071

7172

src/core/modules/memory/memory_wrap.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,13 @@ void export_binary_file(scope _memory)
136136
)
137137

138138
// Attributes
139-
.def_readwrite("address",
140-
&CBinaryFile::m_ulAddr,
139+
.def_readwrite("module",
140+
&CBinaryFile::m_ulModule,
141+
"Handle of the binary."
142+
)
143+
144+
.def_readwrite("base",
145+
&CBinaryFile::m_ulBase,
141146
"Base address of the binary."
142147
)
143148

0 commit comments

Comments
 (0)