That's why I developed an engine that aims to ward off attacks on variables with cheat programs like Cheatengine.
My ideas were there
-Encryption of countless XOR links
-Variable runtime length
-Certain resistance to changes in variables in memory.
There is one problem with this though.. it's extremely slow and that's an understatement.
Requires Freebasic GCC: https://sourceforge.net/projects/fbc/fi ... c-9.3.0.7z
Compile with -t 250000 and it will work
Code:
Code: Select all
'dim shared as integer vx
locate ,,0
type acx_lvl1
value1 as integer
value2 as integer
value3 as integer
key1 as integer
key2 as integer
key3 as integer
khash as integer
vhash as integer
main_hash as integer
declare constructor
declare destructor
declare sub set (value as integer)
declare function get as integer
end type
constructor acx_lvl1
' vx+=1
'print " - ADRESS = ";HEX(@THIS)
value1 = int(rnd*99999999999)
value2 = int(rnd*99999999999)
value3 = int(rnd*99999999999)
do
key1 = int(rnd*99999999999)
key2 = int(rnd*99999999999)
key3 = int(rnd*99999999999)
loop until key1 > 0 and key2 > 0 and key3 > 0
vhash = value1+value2+value3
khash = key1+key2+key3
main_hash = value1 + value2+value3+key1+key2+key3+vhash+khash
end constructor
destructor acx_lvl1
if main_hash <> 0 then
' vx-=1
main_hash = 0
value1 = 0
value2 = 0
value3 = 0
key1 = 0
key2 = 0
key3 = 0
vhash = 0
khash = 0
end if
end destructor
sub acx_lvl1.set(value as integer)
do
key1 = int(rnd*99999999999)
key2 = int(rnd*99999999999)
key3 = int(rnd*99999999999)
loop until key1 > 0 and key2 > 0 and key3 > 0
value1 = value xor key1
value2 = value xor key2
value3 = value xor key3
vhash = value1+value2+value3
khash = key1+key2+key3
main_hash = value1 + value2+value3+key1+key2+key3+vhash+khash
end sub
function acx_lvl1.get as integer
'print "R - ";HEX(@value1);" - ";
if main_hash <> value1 + value2+value3+key1+key2+key3+vhash+khash then
PRINT "E - 5"
return 0
end if
if khash = 0 or vhash = 0 or main_hash = 0 then
PRINT "E - 5B"
return 0
end if
if (vhash = value1+value2+value3) and ( khash = key1+key2+key3) then
if (value1 xor key1) = (value2 xor key2) and (value2 xor key2) = (value3 xor key3) then
if (value1 xor key1) = (value2 xor key2) then return value1 xor key1
PRINT "E - 1B"
if (value1 xor key1) = (value3 xor key3) then return value1 xor key1
if (value2 xor key2) = (value3 xor key3) then return value2 xor key2
PRINT "E - 1C"
return value3 xor key3
else
' PRINT "E - 1"
return 0
end if
PRINT "E - 2"
return 0
end if
end function
type acx_lvl2
v as acx_lvl1
key as acx_lvl1
hash as acx_lvl1
master_hash as acx_lvl1
declare sub set(value as acx_lvl1)
declare function get as acx_lvl1
end type
sub acx_lvl2.set(value as acx_lvl1)
key.set int(rnd*999999999999)
v.set value.get xor key.get
hash.set v.get + key.get
master_hash.set v.get + hash.get + key.get
end sub
function acx_lvl2.get as acx_lvl1
if hash.get = v.get + key.get then
dim tmp as acx_lvl1
tmp.set v.get xor key.get
if master_hash.get = v.get + hash.get + key.get then
return tmp
else
print "E - 3B"
end if
else
print "E - 3"
end if
end function
type acx_lvl3
v as acx_lvl2
k as acx_lvl2
v2 as acx_lvl2
k2 as acx_lvl2
declare sub set (value as integer)
declare function get as integer
end type
sub acx_lvl3.set (value as integer)
dim as acx_lvl1 tv,tk,tk2,tv2
tk.set int(rnd*99999999999)
tk2.set int(rnd*99999999999)
tv.set value xor tk.get
tv2.set value xor tk2.get
v.set tv
k.set tk
v2.set tv2
k2.set tk2
end sub
function acx_lvl3.get as integer
dim as acx_lvl1 tv,tk,tv2,tk2
tv.set v.get.get
tk.set k.get.get
tv2.set v2.get.get
tk2.set k2.get.get
if (tv.get xor tk.get) = (tv2.get xor tk2.get) then
return tv.get xor tk.get
else
print "E - 6"
end if
end function
type ac_ubyte_simple
dim value2 as ubyte
dim value as ubyte
dim key2 as ubyte
dim key as ubyte
dim sabotageflag as ubyte
declare sub set(value as ubyte)
declare function get as ubyte
declare constructor
end type
constructor ac_ubyte_simple
this.set 123
if this.get <> (this.value xor this.key) then sabotageflag = 1
this.set 222
if this.get <> 222 then sabotageflag = 2
end constructor
sub ac_ubyte_simple.set (value as ubyte)
if sabotageflag = 1 then exit sub
this.key = int(rnd*256)
this.value = value xor this.key
this.key2 = int(rnd*256)
this.value2 = value xor this.key2
end sub
function ac_ubyte_simple.get as ubyte
if sabotageflag = 2 then PRINT "E1":this.set int(rnd*256) : sabotageflag = 1
if sabotageflag = 1 then PRINT "E2":exit function
return value xor key
end function
type ac_ubyte_getter
v as ac_ubyte_simple
declare function get as ubyte
declare sub set(value as ubyte)
end type
sub ac_ubyte_getter.set (value as ubyte)
if value <= 10 then
v.set value
end if
end sub
function ac_ubyte_getter.get as ubyte
if v.get <= 10 then
return v.get
else
return 0
end if
end function
type ac_integer
dim m as ac_ubyte_getter
dim om as ac_ubyte_getter
key(10) as acx_lvl3
keycv(10) as acx_lvl3
decheat as acx_lvl3
v(10) as acx_lvl3
cv(10) as acx_lvl3
locked as acx_lvl1
ignore(10) as ac_ubyte_getter
hash as uinteger
declare sub lock_set
declare sub terminatedata
declare sub set(value as integer)
declare function get as integer
declare function gen_hash as integer
end type
sub ac_integer.terminatedata
erase(key)
erase(keycv)
erase(v)
erase(cv)
for i as integer = 0 to 9
ignore(i).set int(rnd*256)
next
m.set 0
om.set 0
hash = 0
end sub
function ac_integer.gen_hash as integer
dim as integer h
for i as integer = lbound(v) to ubound(v)
h += v(i).get + cv(i).get + key(i).get + keycv(i).get + m.get
next
'if h = 0 then sleep 1
return h
end function
sub ac_integer.set(value as integer)
dim as integer valh = value
if decheat.get = 1 or locked.get = 1 then exit sub
if (cv(m.get).get xor keycv(m.get).get) <> (v(m.get).get xor key(m.get).get) then ignore(m.get).set 1
if ignore(m.get).get <> 0 then
dim as integer t = timer
do
m.set ((m.get + 1) mod 10)
if decheat.get = 1 then exit sub
if (timer-t) > .25 then
decheat.set 1
this.terminatedata
exit sub
end if
loop until ignore(m.get).get = 0
end if
if m.get = 10 then
m.set 0
end if
key(m.get).set int(rnd*99999999)
keycv(m.get).set int(rnd*99999999)
cv(m.get).set value xor keycv(m.get).get
v(m.get).set value xor key(m.get).get
if valh <> (v(m.get).get xor key(m.get).get) then hash = 0
if (v(m.get).get xor key(m.get).get) <> value then ignore(m.get).set 1
hash = gen_hash
end sub
function ac_integer.get as integer
if m.get > ubound(v) then PRINT "E3":terminatedata : hash = -1
om.set m.get
if hash <> gen_hash then PRINT "E4":set 0 : decheat.set 1
if decheat.get = 1 then return 0
if (v(m.get).get xor key(m.get).get) <> (cv(m.get).get xor keycv(m.get).get) then return 0
m.set m.get + 1
this.set v(m.get-1).get xor key(m.get-1).get
if om.get = m.get then PRINT "E7":set 0
if m.get > 0 then
return v(m.get).get xor key(m.get).get
else
return v(0).get xor key(0).get
end if
end function
type ac_lv_1
decheatflag as ubyte
value as ac_integer
value2 as ac_integer
key as ac_integer
key2 as ac_integer
hash as integer
declare sub set(v as integer)
declare function get as integer
end type
sub ac_lv_1.set (v as integer)
if decheatflag = 1 then v = 0
key.set int(rnd*99999999)
key2.set int(rnd*99999999)
value.set v xor key.get '+ 1
value2.set v xor key2.get
hash = value.get + value2.get
if (value.get xor key.get) <> v then print "X -2":decheatflag = 1
end sub
function ac_lv_1.get as integer
if hash = value.get + value2.get then
return value.get xor key.get
else
PRINT "X -1"
value.decheat.set 1 : value2.decheat.set 1
return 0
end if
end function
type ac_lv_2
value as ac_lv_1
value2 as ac_lv_1
key as ac_lv_1
key2 as ac_lv_1
hash as ac_lv_1
declare sub set (v as integer)
declare function get as integer
end type
sub ac_lv_2.set (v as integer)
key.set int(rnd*9999999)
key2.set int(rnd*9999999)
value.set v xor key.get
value2.set v xor key2.get
hash.set (value.value.get + value2.value.get)
end sub
function ac_lv_2.get as integer
if hash.get = value.value.get + value2.value.get then
return value.get xor key.get '+ int(rnd *2000)
else
PRINT "X0"
return 0
end if
end function
type ac_lv_3
value(9) as ac_lv_2
key(9) as ac_lv_2
readcycles as ac_lv_2 'count the cycles of reading
declare sub set (value as integer)
declare function get as integer
locked as ac_lv_2
end type
sub ac_lv_3.set (value as integer)
if locked.get <> 0 then PRINT "X1":exit sub
for i as integer = 0 to 8
key(i).set int(rnd*999999999)
this.value(i).set value xor key(i).get
next
end sub
function ac_lv_3.get as integer
if locked.get = 2 then PRINT "X2": return 0
readcycles.set 0
dim as ac_lv_2 h
for i as integer = 0 to 8
readcycles.set readcycles.get + 1
if (this.value(i).get xor key(i).get) = (this.value(i+1).get xor key(i+1).get) then
h.set h.get + 1
end if
next
if h.get = 8 then
dim as ac_lv_2 sum
for i as integer = 0 to 8
readcycles.set readcycles.get + 1
sum.set sum.get + (this.value(i).get xor this.key(i).get)
next
if sum.get = 0 then return 0
if cint(sum.get) / 9 <> (this.value(1).get xor this.key(1).get) then
return this.value(1).get xor this.key(1).get
else
if readcycles.get <> 18 then this.set 0 : return 0
return cint(sum.get) / 9' + int(rnd*2)
end if
return 0
end if
end function
type ac_lv_4
value1 as ac_lv_3
value2 as ac_lv_3
key1 as ac_lv_3
key2 as ac_lv_3
hash as ac_lv_3
dim as ac_ubyte_simple usemax_flag,decheat
dim as ac_integer max_movement
lockctrl_passcode as integer
declare sub set(value as integer)
declare function get as integer
declare sub lockctrl(value as integer,passcode as integer = 0)
declare sub enable_max_movement
declare sub set_max_movement(value as integer)
declare function lockreader as integer
declare sub disable
declare constructor () ' use this to lock access as default
end type
constructor ac_lv_4
lockctrl_passcode = int(rnd*99999999)
lockctrl 1,lockctrl_passcode
end constructor
function ac_lv_4.lockreader as integer
return(value1.locked.get + value2.locked.get) / 2
end function
sub ac_lv_4.enable_max_movement
usemax_flag.set 1
end sub
sub ac_lv_4.set_max_movement(value as integer)
max_movement.set 100
end sub
sub ac_lv_4.set (value as integer)
Print "A";
if usemax_flag.get = 1 then
PRINT "B";
if (value >= (get + max_movement.get)) or (value <= (get - max_movement.get)) then usemax_flag.set 0 : set 0 : decheat.set 1 : usemax_flag.set 1 : this.value1.set 0 : lockctrl 1, lockctrl_passcode : lockctrl_passcode = 0 : exit sub
print "C";
end if
PRINT "D";
key1.set int(rnd*999999)
PRINT "E";
key2.set int(rnd*999999)
PRINT "F";
value1.set value xor key1.get
print "H";
value2.set value1.get xor key2.get
PRINT "I";
value1.set 0
end sub
function ac_lv_4.get as integer
if decheat.get = 1 then return 0
return (value2.get xor key2.get) xor key1.get
end function
sub ac_lv_4.lockctrl (value as integer,passcode as integer = 0)
' print "LOCK CTRL",value
if lockctrl_passcode = 0 then EXIT SUB
if (passcode > 0) and (lockctrl_passcode > 0) and (passcode = lockctrl_passcode) then
' PRINT "ACCSESS ALLOWED"
select case value
case 1
value1.locked.set 1
value2.locked.set 1
key1.locked.set 1
key2.locked.set 1
hash.locked.set 1
' PRINT "LOCKED"
case 0
value1.locked.set 0
value2.locked.set 0
key1.locked.set 0
key2.locked.set 0
hash.locked.set 0
' PRINT "UNLOCKED"
case else
'Print "LOCK CONTROL ERROR - UNSOPPORTED LOCK STATE"
end select
else
'print "ACCESS DENINED",passcode,lockctrl_passcode,value
lockctrl 1, lockctrl_passcode
end if
end sub
sub ac_lv_4.disable
lockctrl 1,lockctrl_passcode
value1.set 0
value2.set 0
key1.set 0
key2.set 0
hash.set 0
lockctrl 1,lockctrl_passcode
end sub
sub pass(state as ubyte)
select case state
case 1
print "PASSED"
case else
color 12
print "NOT PASSED"
beep
sleep
end
end select
color 7
end sub
'main area
Print "THE UNCHEATABLE VALUE - PROTOTYPE"
print "BUILD..";
dim shared as ac_lv_4 example
PRINT "OK"
print "INIT"
print 1
print 2
dim as ac_lv_3 ov,nv
print 3
dim as ubyte cid
print 4
dim as string chartbl = "|/-\"
print 5
const init_val = 10000
print 6
dim as ubyte initalized
print 7
Print "Setup";
example.lockctrl 0,example.lockctrl_passcode
print ".";
example.max_movement.set 10000
print ".";
example.set 1000
print ".";
example.max_movement.set 1
print ".";
example.max_movement.locked.set 1
print ".";
example.lockctrl 1,example.lockctrl_passcode
print " DONE"
sleep 250
color 7
dim as string k
dim as integer buf
do
cls
locate 1,10
'print vx
locate 1,1
print "CHANGE THIS VALUE -->";
color 15
print example.get;
color 7
print " TO 12345 WITH CHEATENGINE- GOOD LOOK :)"
print "+ to incrase the value, ESC to exit"
buf = example.get
Print "Waiting for input..";
k = input(1)
select case k
case "+"
Print "Incrasing Value, please wait..";
example.lockctrl 0,example.lockctrl_passcode
example.set example.get + 1
example.lockctrl 1,example.lockctrl_passcode
Print "done."
case chr(27)
exit do
end select
loop until buf = 12345
if buf = 12345 then print "CONGRATULATIONS YOU DID IT!"
sleep