@@ -112,23 +112,55 @@ implementation
112112uses
113113 TypInfo;
114114
115- function IsClassPtr (p: Pointer): Boolean;
116- begin
117- try
118- Result := PPointer(NativeInt(p) + vmtSelfPtr)^ = p;
119- except
120- Result := False;
115+ function IsValidObj (p: PPointer): Boolean;
116+ { $IFDEF MSWINDOWS}
117+ var
118+ memInfo: TMemoryBasicInformation;
119+ { $ENDIF}
120+
121+ function IsValidPtr (address: Pointer): Boolean;
122+ begin
123+ // Must be above 64k and 4 byte aligned
124+ if (UIntPtr(address) > $FFFF) and (UIntPtr(address) and 3 = 0 ) then
125+ begin
126+ { $IFDEF MSWINDOWS}
127+ // do we need to recheck the virtual memory?
128+ if (UIntPtr(memInfo.BaseAddress) > UIntPtr(address))
129+ or ((UIntPtr(memInfo.BaseAddress) + memInfo.RegionSize) < (UIntPtr(address) + SizeOf(Pointer))) then
130+ begin
131+ // retrieve the status for the pointer
132+ memInfo.RegionSize := 0 ;
133+ VirtualQuery(address, memInfo, SizeOf(memInfo));
134+ end ;
135+ // check the readability of the memory address
136+ Result := (memInfo.RegionSize >= SizeOf(Pointer))
137+ and (memInfo.State = MEM_COMMIT)
138+ and (memInfo.Protect and (PAGE_READONLY or PAGE_READWRITE
139+ or PAGE_WRITECOPY or PAGE_EXECUTE or PAGE_EXECUTE_READ
140+ or PAGE_EXECUTE_READWRITE or PAGE_EXECUTE_WRITECOPY) <> 0 )
141+ and (memInfo.Protect and PAGE_GUARD = 0 );
142+ { $ELSE}
143+ Result := True;
144+ { $ENDIF}
145+ end
146+ else
147+ Result := False;
121148 end ;
122- end ;
123149
124- function IsValidObj (p: Pointer): Boolean;
125150begin
126151 Result := False;
127152 if Assigned(p) then
128153 try
129- if not IsClassPtr(p) then
130- if PNativeInt(p)^ > $FFFF then
131- Result := PPointer(p)^ = PPointer(PNativeInt(p)^ + vmtSelfPtr)^;
154+ { $IFDEF MSWINDOWS}
155+ memInfo.RegionSize := 0 ;
156+ { $ENDIF}
157+ if IsValidPtr(PByte(p) + vmtSelfPtr)
158+ // not a class pointer - they point to themselves in the vmtSelfPtr slot
159+ and (p <> PPointer(PByte(p) + vmtSelfPtr)^) then
160+ if IsValidPtr(p) and IsValidPtr(PByte(p^) + vmtSelfPtr)
161+ // looks to be an object, it points to a valid class pointer
162+ and (p^ = PPointer(PByte(p^) + vmtSelfPtr)^) then
163+ Result := True;
132164 except
133165 end ; // FI:W501
134166end ;
0 commit comments