Sicro wrote:The PB help describes that the purifier of the debugger checks not only memories but also variables, whether the current process reads or writes outside the valid range
...
Looks like the purifier isn't working properly then.
I believe the purify has nothing to do with integer overflows.
It checks if strings, variables, or allocated memory boundaries are overshoot when writing to memory.
So it is working properly accordingly to what specified in the help file:
help wrote:
The purifier detects these errors by placing a special 'salt'-value around global and local variables, strings and allocated memory buffers. These salt values are then checked at regular intervals and an error is displayed if they were changed.
To clarify what it does and what it does not run these examples on x86 with the purifier enabled in compiler options.
Code: Select all
#enable_purifier_checks = 1
CompilerIf #enable_purifier_checks
PurifierGranularity(0,1,0,0)
CompilerElse
PurifierGranularity(0,0,0,0)
CompilerEndIf
Procedure foo()
Protected a,b,c
a = 1
b = 2
c = 3
;PokeB(@a+3, $80) ; this is ok, writes inside 'a'
;ShowMemoryViewer(@a,256)
PokeB(@a+4, $80) ; this is not ok, writes outside 'a'
ShowMemoryViewer(@a,256)
Debug a
Debug b
Debug c
EndProcedure
foo()
In this example looking at the output of ShowMemoryViewer() you can actually see the salt values added by the purifier after the four bytes of each integer allocated on the stack.
PokeB(@a+3, $80) works as expected because it is writing inside the boundaries of 'a', changing the value of the integer.
PokeB(@a+4, $80) writes outside and tamper the stacks altering the value of 'b' (if the purifier is disabled). The purifier detects this because its salt is being altered instead.
Code: Select all
Waiting for executable to start...
Executable type: Windows - x86 (32bit, Unicode, Purifier)
Executable started.
[ERROR] Line: 19
[ERROR] Procedure stack has been corrupted.
Same mechanism is used for strings and memory buffers.
Code: Select all
#enable_purifier_checks = 1
CompilerIf #enable_purifier_checks
PurifierGranularity(0,1,0,0)
CompilerElse
PurifierGranularity(0,0,0,0)
CompilerEndIf
#MAX_INTEGER = 1 << 31 - 1
Procedure foo()
Protected a,b,c
a = #MAX_INTEGER
Debug a
a = #MAX_INTEGER + 1 ; bits are going to overflow
Debug a
EndProcedure
foo()
This is something the purifier does not care about, all is happening inside the variable's boundaries.
The integer overflow just cause the signed integer to wrap around as expected.