How to hack certain properties

Blitz3D Forums/Blitz3D Tutorials/How to hack certain properties

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

This is about how to hack certain properties. Sometimes you will miss a function that will tell you about some settings of a entity or something. One example is "how to determine a brushes alpha setting", that is needed when calculating the visibility of surfaces. Instead of requesting for new features you may try to help yourself and solve the problem as a hacker.

Note: it is not sure if these hacks will still work with future versions of the blitz3D compiler, although it's likely.

What we do is: we take the handle of eg. the brush. We assume this handle is the adress of a pointer to the brush structure. So we read the 32 bit adress found at adress HANDLE. Now we scan the memory beginning at that adress. If we are going to find our highly individual brush setting float then we can assume we have found the offset of the alpha parameter in the brush structure.

This method uses the RTLMoveMemory command so you need a decls file named "kernel32.decls" in your "userlibs" folder, containing at least the following lines:
.lib "kernel32.dll"
RTLMoveMemory2%(Destination*, Source, Length) : "RTLMoveMemory"


RTLMoveMemory2 is used to read the RAM at absolute adresses.

The following example will search for the Alpha setting of a brush. With a little editing it can easily be used to search for other things as well.
Graphics3D 640,480,32,2
SetBuffer BackBuffer()

magic#=0.314159 ; tag used in search

brush=CreateBrush(100,150,200) ; create a dummy brush
BrushAlpha brush,magic#

ba=CreateBank(8)
PokeFloat ba,0,magic# ; get the integer binary equivalent of magic# (using Float directy fails due to NAN values)
magic_i%=PeekInt(ba,0)
FreeBank ba


bank=CreateBank(8) ; used to receive alpha value
adr_bank=CreateBank(8) ; used to receive base adress

For i2=0 To 100 Step 2 ; most pointers may be below 100 and even offsets
 RtlMoveMemory2(adr_bank,brush+i2,4) ; read potential base adress
 adr=PeekInt(adr_bank,0)
 For i=0 To 65535 
  RtlMoveMemory2(bank,adr+i,4) ; seek magic value
  magic_i2%=PeekInt(bank,0)
  If magic_i%=magic_i2% Then
   Print "found:"
   Print "base adress taken from: brush+"+i2
   Print "offset: "+i
  EndIf
  If KeyDown(1) Then End
 Next
Next

Print
Print "ok"
Print


; if an adress is once known it's value can be accessed directly like this:
RtlMoveMemory2(adr_bank,brush+0,4) ; determine absolute adress of a brushes alpha setting
adr=PeekInt(adr_bank,0)+32
RtlMoveMemory2(bank,adr,4) ; read alpha to bank
alpha#=PeekFloat(bank,0)
Print "alpha#: "+alpha#



WaitKey()
End


Of course the same can also be used with integer parameters, after replacing the float access parts.

BTW this program goes further than simply trying to use the HANDLE as pointer, it will also try a number of pointers taken at HANDLE + i2, although if present a parameter will most likely be found in the structure found at pointer HANDLE.