@@ -130,6 +130,7 @@ namespace CLEO
130
130
OpcodeResult __stdcall opcode_2001 (CRunningScript* thread); // get_script_filename
131
131
OpcodeResult __stdcall opcode_2002 (CRunningScript* thread); // cleo_return_with
132
132
OpcodeResult __stdcall opcode_2003 (CRunningScript* thread); // cleo_return_fail
133
+ OpcodeResult __stdcall opcode_2004 (CRunningScript* thread); // forget_memory
133
134
134
135
typedef void (*FuncScriptDeleteDelegateT) (CRunningScript *script);
135
136
struct ScriptDeleteDelegate {
@@ -406,6 +407,7 @@ namespace CLEO
406
407
CLEO_RegisterOpcode (0x2001 , opcode_2001); // get_script_filename
407
408
CLEO_RegisterOpcode (0x2002 , opcode_2002); // cleo_return_with
408
409
CLEO_RegisterOpcode (0x2003 , opcode_2003); // cleo_return_fail
410
+ CLEO_RegisterOpcode (0x2004 , opcode_2004); // forget_memory
409
411
}
410
412
411
413
void CCustomOpcodeSystem::Inject (CCodeInjector& inj)
@@ -2472,10 +2474,21 @@ namespace CLEO
2472
2474
// 0AC8=2,%2d% = allocate_memory_size %1d%
2473
2475
OpcodeResult __stdcall opcode_0AC8 (CRunningScript *thread)
2474
2476
{
2475
- DWORD size;
2476
- *thread >> size;
2477
- void *mem = malloc (size);
2478
- if (mem) GetInstance ().OpcodeSystem .m_pAllocations .insert (mem);
2477
+ DWORD size; *thread >> size;
2478
+
2479
+ void * mem = malloc (size);
2480
+ if (mem)
2481
+ {
2482
+ DWORD oldProtect;
2483
+ VirtualProtect (mem, size, PAGE_EXECUTE_READWRITE, &oldProtect);
2484
+
2485
+ GetInstance ().OpcodeSystem .m_pAllocations .insert (mem);
2486
+ }
2487
+ else
2488
+ {
2489
+ LOG_WARNING (thread, " [0AC8] failed to allocate of %d bytes memory in script %s" , size, ((CCustomScript*)thread)->GetInfoStr ().c_str ());
2490
+ }
2491
+
2479
2492
*thread << mem;
2480
2493
SetScriptCondResult (thread, mem != nullptr );
2481
2494
return OR_CONTINUE;
@@ -2484,14 +2497,24 @@ namespace CLEO
2484
2497
// 0AC9=1,free_allocated_memory %1d%
2485
2498
OpcodeResult __stdcall opcode_0AC9 (CRunningScript *thread)
2486
2499
{
2487
- void *mem;
2488
- *thread >> mem;
2500
+ void *mem; *thread >> mem;
2501
+
2502
+ if ((size_t )mem <= CCustomOpcodeSystem::MinValidAddress)
2503
+ {
2504
+ SHOW_ERROR (" [0AC9] used with invalid '0x%X' pointer argument in script %s\n Script suspended." , mem, ((CCustomScript*)thread)->GetInfoStr ().c_str ());
2505
+ return CCustomOpcodeSystem::ErrorSuspendScript (thread);
2506
+ }
2507
+
2508
+ // allocated with 0AC8
2489
2509
auto & allocs = GetInstance ().OpcodeSystem .m_pAllocations ;
2490
2510
if (allocs.find (mem) != allocs.end ())
2491
2511
{
2492
2512
free (mem);
2493
2513
allocs.erase (mem);
2514
+ return OR_CONTINUE; // done
2494
2515
}
2516
+
2517
+ LOG_WARNING (thread, " [0AC9] used with pointer to unknown or already freed memory in script %s" , ((CCustomScript*)thread)->GetInfoStr ().c_str ());
2495
2518
return OR_CONTINUE;
2496
2519
}
2497
2520
@@ -3109,6 +3132,29 @@ namespace CLEO
3109
3132
SetScriptCondResult (thread, false );
3110
3133
return GetInstance ().OpcodeSystem .CleoReturnGeneric (0x2003 , thread);
3111
3134
}
3135
+
3136
+ // 2004=1,forget_memory %1d%
3137
+ OpcodeResult __stdcall opcode_2004 (CRunningScript* thread)
3138
+ {
3139
+ void * mem; *thread >> mem;
3140
+
3141
+ if ((size_t )mem <= CCustomOpcodeSystem::MinValidAddress)
3142
+ {
3143
+ SHOW_ERROR (" [2004] used with invalid '0x%X' pointer argument in script %s\n Script suspended." , mem, ((CCustomScript*)thread)->GetInfoStr ().c_str ());
3144
+ return CCustomOpcodeSystem::ErrorSuspendScript (thread);
3145
+ }
3146
+
3147
+ // allocated with 0AC8
3148
+ auto & allocs = GetInstance ().OpcodeSystem .m_pAllocations ;
3149
+ if (allocs.find (mem) != allocs.end ())
3150
+ {
3151
+ allocs.erase (mem);
3152
+ return OR_CONTINUE; // done
3153
+ }
3154
+
3155
+ LOG_WARNING (thread, " [2004] used with pointer to unknown or already freed memory in script %s" , ((CCustomScript*)thread)->GetInfoStr ().c_str ());
3156
+ return OR_CONTINUE;
3157
+ }
3112
3158
}
3113
3159
3114
3160
0 commit comments