Improve Debug build and JIT script execution
- Use VirtualAlloc with PAGE_EXECUTE_READWRITE for JIT code buffers - Remove DEP disable flag, rely on proper memory allocation instead - Allow Debug build to use command-line IP args (fallback to 127.0.0.1) - Add CHANGELOG.md documenting all recent fixes
This commit is contained in:
30
CHANGELOG.md
Normal file
30
CHANGELOG.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [2024-11-30] - Build System & Script Engine Fixes
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **Release_NoGD Configuration**: Added missing compiler settings (SSE2, OpenMP, warning suppressions) to match Release configuration
|
||||||
|
- **Debug Build Linker Error**: Added `_USE_32BIT_TIME_T` preprocessor definition to GlobalScript Debug configuration to fix `ParsePacket::HandleUserLogin` time_t size mismatch (LNK2019)
|
||||||
|
- **Script Execution Crash**: Implemented VirtualAlloc with PAGE_EXECUTE_READWRITE for JIT code buffer allocation to resolve DEP-related memory access violations
|
||||||
|
- **Standalone Debugging**: Modified `_RYL_TEST` mode to automatically enable `ADMIN_L3` without requiring Login.exe
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- **Working Directory**: Set LocalDebuggerWorkingDirectory to `F:\YouxiLand\ROW` for all configurations to enable proper resource loading during debugging
|
||||||
|
- **Server IP Handling**: Modified `GetServerInfo()` to respect command-line IP arguments even in Debug builds, falling back to `127.0.0.1` only when no IP is provided
|
||||||
|
- **Memory Management**: Enhanced `CVirtualMachine::Destroy()` to properly detect and free VirtualAlloc-allocated memory using VirtualQuery
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- **Debug Logging**: Added MCF file decryption logging (`.decrypted.log` files) for script debugging
|
||||||
|
- **Execute State Logging**: Added comprehensive state logging to `script_execute.log` before script execution
|
||||||
|
|
||||||
|
### Technical Details
|
||||||
|
- MCF XOR encryption key: `0x82fac623 ^ 0x601f1ac4`
|
||||||
|
- Stack reserve size increased to 8MB for Debug configuration
|
||||||
|
- Code buffer now allocated with executable permissions for JIT execution compatibility with Windows 10/11 DEP
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
- Visual Studio 2010 project
|
||||||
|
- DirectX 8 graphics API
|
||||||
|
- Custom JIT script engine with x86 machine code execution
|
||||||
@@ -137,7 +137,6 @@
|
|||||||
<ProgramDatabaseFile>$(OutDir)Client.pdb</ProgramDatabaseFile>
|
<ProgramDatabaseFile>$(OutDir)Client.pdb</ProgramDatabaseFile>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<StackReserveSize>8388608</StackReserveSize>
|
<StackReserveSize>8388608</StackReserveSize>
|
||||||
<DataExecutionPrevention>false</DataExecutionPrevention>
|
|
||||||
<TargetMachine>MachineX86</TargetMachine>
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
<EnableUAC>false</EnableUAC>
|
<EnableUAC>false</EnableUAC>
|
||||||
<UACExecutionLevel>HighestAvailable</UACExecutionLevel>
|
<UACExecutionLevel>HighestAvailable</UACExecutionLevel>
|
||||||
|
|||||||
@@ -603,6 +603,10 @@ VOID CClientMain::GetServerInfo( HWND hWnd )
|
|||||||
{
|
{
|
||||||
char *strCommandLine = GetCommandLine() ;
|
char *strCommandLine = GetCommandLine() ;
|
||||||
|
|
||||||
|
// 기본값으로 초기화
|
||||||
|
strcpy(CRYLNetworkData::m_strIP, "");
|
||||||
|
CRYLNetworkData::m_dwServerID = 0;
|
||||||
|
|
||||||
if ( hWnd )
|
if ( hWnd )
|
||||||
{
|
{
|
||||||
char *pLast = strCommandLine ;
|
char *pLast = strCommandLine ;
|
||||||
@@ -612,12 +616,19 @@ VOID CClientMain::GetServerInfo( HWND hWnd )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *pLast = strrchr( strCommandLine, '"' ) ;
|
char *pLast = strrchr( strCommandLine, '"' ) ;
|
||||||
pLast += 2 ;
|
if (pLast)
|
||||||
sscanf( pLast,"%s %d", CRYLNetworkData::m_strIP, &CRYLNetworkData::m_dwServerID ) ;
|
{
|
||||||
|
pLast += 2 ;
|
||||||
|
sscanf( pLast,"%s %d", CRYLNetworkData::m_strIP, &CRYLNetworkData::m_dwServerID ) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
strcpy(CRYLNetworkData::m_strIP, "127.0.0.1");
|
// 명령줄에서 IP를 받지 못한 경우에만 기본값 사용
|
||||||
|
if (strlen(CRYLNetworkData::m_strIP) == 0 || strcmp(CRYLNetworkData::m_strIP, "") == 0)
|
||||||
|
{
|
||||||
|
strcpy(CRYLNetworkData::m_strIP, "127.0.0.1");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
if ( m_wAdminMode == ADMIN_L3 )
|
if ( m_wAdminMode == ADMIN_L3 )
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "GMMemory.h"
|
#include "GMMemory.h"
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
|
|
||||||
@@ -232,7 +233,11 @@ void CVirtualMachine::Create( const void * pDataBuf, unsigned DataSize )
|
|||||||
|
|
||||||
TotalBufferSize = GlobalVarBufferSize + StringBufferSize + m_iCodeSize;
|
TotalBufferSize = GlobalVarBufferSize + StringBufferSize + m_iCodeSize;
|
||||||
|
|
||||||
m_pGlobalVars = m_pBuffer = new char[TotalBufferSize];
|
// Use VirtualAlloc for executable code buffer
|
||||||
|
m_pGlobalVars = m_pBuffer = (char*)VirtualAlloc(NULL, TotalBufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
|
if (m_pBuffer == NULL) {
|
||||||
|
m_pGlobalVars = m_pBuffer = new char[TotalBufferSize];
|
||||||
|
}
|
||||||
m_pStringBuffer = ((byte*)m_pGlobalVars) + GlobalVarBufferSize;
|
m_pStringBuffer = ((byte*)m_pGlobalVars) + GlobalVarBufferSize;
|
||||||
m_pCodeBuffer = ((byte*)m_pStringBuffer) + StringBufferSize;
|
m_pCodeBuffer = ((byte*)m_pStringBuffer) + StringBufferSize;
|
||||||
|
|
||||||
@@ -277,7 +282,11 @@ void CVirtualMachine::Create( CIntermediateCode & IMCode, CSymbolTable & Symbo
|
|||||||
int StringBufferSize = SymbolTable.GetStringBufferSize();
|
int StringBufferSize = SymbolTable.GetStringBufferSize();
|
||||||
int BufSize = GlobalVarsSize + StringBufferSize + m_iCodeSize;
|
int BufSize = GlobalVarsSize + StringBufferSize + m_iCodeSize;
|
||||||
|
|
||||||
m_pGlobalVars = m_pBuffer = new char[ BufSize ];
|
// Use VirtualAlloc for executable code buffer
|
||||||
|
m_pGlobalVars = m_pBuffer = (char*)VirtualAlloc(NULL, BufSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
|
if (m_pBuffer == NULL) {
|
||||||
|
m_pGlobalVars = m_pBuffer = new char[ BufSize ];
|
||||||
|
}
|
||||||
|
|
||||||
memset( m_pGlobalVars, 0, GlobalVarsSize );
|
memset( m_pGlobalVars, 0, GlobalVarsSize );
|
||||||
|
|
||||||
@@ -329,7 +338,15 @@ void CVirtualMachine::SetSysVars()
|
|||||||
|
|
||||||
void CVirtualMachine::Destroy()
|
void CVirtualMachine::Destroy()
|
||||||
{
|
{
|
||||||
delete [] m_pBuffer;
|
// Check if buffer was allocated with VirtualAlloc (aligned to 4KB/64KB boundary typically)
|
||||||
|
if (m_pBuffer != NULL) {
|
||||||
|
MEMORY_BASIC_INFORMATION mbi;
|
||||||
|
if (VirtualQuery(m_pBuffer, &mbi, sizeof(mbi)) && mbi.AllocationBase == m_pBuffer) {
|
||||||
|
VirtualFree(m_pBuffer, 0, MEM_RELEASE);
|
||||||
|
} else {
|
||||||
|
delete [] m_pBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
m_pBuffer = m_pGlobalVars = m_pStringBuffer = m_pCodeBuffer = NULL;
|
m_pBuffer = m_pGlobalVars = m_pStringBuffer = m_pCodeBuffer = NULL;
|
||||||
m_iCodeSize = 0;
|
m_iCodeSize = 0;
|
||||||
m_pFunctionMap->clear();
|
m_pFunctionMap->clear();
|
||||||
|
|||||||
Reference in New Issue
Block a user