| View previous topic :: View next topic | 
	
	
		| Author | Message | 
	
		| AylinCE Grandmaster Cheater Supreme
 
  Reputation: 37 
 Joined: 16 Feb 2017
 Posts: 1528
 
 
 | 
			
				|  Posted: Wed Oct 01, 2025 6:57 am    Post subject: Parsing a number from an address (Double~Int) |   |  
				| 
 |  
				| We aim to contribute to the CE and CEF archives as much as possible. 
 Please support further sharing on this topic.
 
 I have a project where I need to parse whether a number retrieved from an address is a "Double" or an "Integer."
 
 I'll probably compare the results of a vtAll scan of a mixture of 4 bytes and Doubles and add them to the address list.
 
 Here's the parsing method I want to use:
 
 
  	  | Code: |  	  | function getAOB(address, length) local bytestring1={}
 local str=''
 bytestring1=readBytes(address, tonumber(length), true)
 
 for i,k in pairs(bytestring1) do
 str=str..string.format('%02x ',bytestring1[i])
 end
 return str:upper()
 end
 
 function isLikelyDouble(d, i, aob)
 if math.abs(d) < 1e-100 and i ~= 0 then
 return false
 end
 
 if d == 0.0 and i == 0 then
 if aob:match("^00 00 00 00 00 00 00 00$") then
 return true
 else
 return false
 end
 end
 
 if d ~= math.floor(d) then
 return true
 end
 
 local maxInt32 = 2147483648
 if math.abs(d) >= maxInt32 then
 return true
 end
 
 local leading4Bytes = aob:match("^%x%x %x%x %x%x %x%x")
 if d == math.floor(d) and leading4Bytes:match("^00 00 00 00$") then
 return true
 end
 
 return false
 end
 
 function readUnsignedInt(addr, opt)
 local signed = readInteger(addr, true)
 if opt then
 if signed < 0 then
 return signed + 4294967296 -- 2^32
 else
 return signed
 end
 else
 return signed
 end
 end
 
 function checkType(addr)
 local d = readDouble(addr)
 local i = readInteger(addr, true)
 local aob = getAOB(addr, 8)
 local res = ""
 
 if isLikelyDouble(d, i, aob) then
 res = string.format("Likely DOUBLE: %.12f - %s", d, aob)
 else
 res = string.format("Likely INT: %d - %s", readUnsignedInt(addr, true), aob)
 end
 
 print(res)
 end
 
 
 addr1 = "14C14398F50" -- Double
 checkType(addr1)
 addr2 = "7B589EF2D8" -- Int
 checkType(addr2)
 addr3 = "14C03478FA0" -- Double
 checkType(addr3)
 addr4 = "7B589FEC38" -- Int
 checkType(addr4)
 addr5 = "7B589FECF0" -- Int ( unsigned: 2863311530, true / signed: -1431655766, false )
 checkType(addr5)
 | 
 
 result:
 Likely DOUBLE: 999.125000000000 - 02 00 00 00 00 39 8F 40
 Likely INT: 100 - 64 00 00 00 00 00 00 00
 Likely DOUBLE: 1000.876464843750 - 01 00 00 00 03 47 8F 40
 Likely INT: 2863311530 - AA AA AA AA AA AA AA AA
 Likely INT: 0 - 00 00 00 00 00 00 00 00
 
 If you have an idea for a better approach to this issue, please contribute to improve the code.
 _________________
 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Wed Oct 01, 2025 11:00 am    Post subject: |   |  
				| 
 |  
				| CE has the Lua function autoGuess that guesses what type the value at some address is. 
 
  	  | Code: |  	  | function byteTableToAOB(bt) local t = {}
 for i,b in ipairs(bt) do
 t[i] = ('%02X'):format(b)
 end
 return table.concat(t, ' ')
 end
 
 function checkType(addr)
 local g = autoGuess(addr)
 if g == vtDouble then
 local bt = readBytes(addr, 8, true)
 print(('double: %.12f - %s'):format(byteTableToDouble(bt), byteTableToAOB(bt)))
 elseif g == vtDword then
 local bt = readBytes(addr, 4, true)
 print(('int: %d - %s'):format(byteTableToDword(bt), byteTableToAOB(bt)))
 else
 print('Other type:', g)  -- see defines.lua
 end
 end
 | 
 _________________
 
 I don't know where I'm going, but I'll figure it out when I get there. |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| AylinCE Grandmaster Cheater Supreme
 
  Reputation: 37 
 Joined: 16 Feb 2017
 Posts: 1528
 
 
 | 
			
				|  Posted: Wed Oct 01, 2025 2:37 pm    Post subject: |   |  
				| 
 |  
				|  	  | ParkourPenguin wrote: |  	  | CE has the Lua function autoGuess ... | 
 
 This is promising code, thanks.
 
 But there's a global bug in "autoGuess" in 7.5.
 Has this been defined?
 _________________
 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Dark Byte Site Admin
 
  Reputation: 470 
 Joined: 09 May 2003
 Posts: 25807
 Location: The netherlands
 
 | 
			
				|  Posted: Wed Oct 01, 2025 3:38 pm    Post subject: |   |  
				| 
 |  
				| you can always use onAutoGuess to fix whatever bug you think it has 
 e.g when CE thinks something is a pointer, because the value it represents is dividable by 8 and the address it represents is readable , you can tell it, no, it's a double/float/int/whatever
 _________________
 
 Do not ask me about online cheats. I don't know any and wont help finding them.
 Like my help? Join me on Patreon so i can keep helping
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| AylinCE Grandmaster Cheater Supreme
 
  Reputation: 37 
 Joined: 16 Feb 2017
 Posts: 1528
 
 
 | 
			
				|  Posted: Wed Oct 01, 2025 4:28 pm    Post subject: |   |  
				| 
 |  
				| So why "nil"? 
 
  	  | Code: |  	  | function byteTableToAOB(bt) local t = {}
 for i,b in ipairs(bt) do
 t[i] = ('%02X'):format(b)
 end
 return table.concat(t, ' ')
 end
 
 function checkType(addr)
 local g = onAutoGuess(addr) -- > g = nil ..
 if g == vtDouble then
 local bt = readBytes(addr, 8, true)
 print(('double: %.12f - %s'):format(byteTableToDouble(bt), byteTableToAOB(bt)))
 elseif g == vtDword then
 local bt = readBytes(addr, 4, true)
 print(('int: %d - %s'):format(byteTableToDword(bt), byteTableToAOB(bt)))
 else
 print(('Other type: %s'):format(g))  -- see defines.lua
 end
 end
 
 addr1 = 0x1824006473F8 -- Double
 checkType(addr1)
 addr2 = "29AA1FEE10" -- Int
 checkType(addr2)
 addr3 = "3220047A352" -- Double
 checkType(addr3)
 addr4 = "3220018B4EC" -- Int
 checkType(addr4)
 | 
 
 result:
 
 Other type: nil
 Other type: nil
 Other type: nil
 Other type: nil
 _________________
 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Wed Oct 01, 2025 4:31 pm    Post subject: |   |  
				| 
 |  
				| I think `autoGuess` became a global function in 7.6. I can't find it in the github repository. 
 `onAutoGuess` is used to override CE's default type-guessing behaviour.
 _________________
 
 I don't know where I'm going, but I'll figure it out when I get there. |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Dark Byte Site Admin
 
  Reputation: 470 
 Joined: 09 May 2003
 Posts: 25807
 Location: The netherlands
 
 | 
			
				|  Posted: Wed Oct 01, 2025 4:59 pm    Post subject: |   |  
				| 
 |  
				| right. in 7.5 you'd have to use the structure class
 
  	  | Code: |  	  | function autoGuess(address)
 local sf=enumStructureForms()
 if #sf==0 then --autoGuess needs a dissect struct form to exist in ce 7.5
 f=createStructureForm()
 f.hide()
 end
 
 local s=createStructure('temp')
 
 local as
 if type(address)~='string' then
 as=string.format('%x',address)
 else
 as=address
 end
 
 s.autoGuess(as,0,16)
 local result
 if s.Count>0 then
 result=s[0].VarType
 else
 result=nil
 end
 s.destroy()
 return result
 end
 
 | 
 _________________
 
 Do not ask me about online cheats. I don't know any and wont help finding them.
 Like my help? Join me on Patreon so i can keep helping
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| AylinCE Grandmaster Cheater Supreme
 
  Reputation: 37 
 Joined: 16 Feb 2017
 Posts: 1528
 
 
 | 
			
				|  Posted: Wed Oct 01, 2025 6:47 pm    Post subject: |   |  
				| 
 |  
				| I think it defines fractional numbers as bytes. 
 
  	  | Code: |  	  | function autoGuess(address) local sf = enumStructureForms()
 if #sf == 0 then
 local f = createStructureForm()
 f.hide()
 end
 
 local s = createStructure('temp')
 local as = type(address) == 'string' and address or string.format('%x', address)
 
 s:autoGuess(as, 0, 16)
 
 local result = nil
 local e = s:getElement(0)
 if e and e.Vartype then
 print("Element 0 type:", e.VarType)
 result = e.VarType
 end
 
 s:destroy()
 return result
 end
 | 
 
 addr1 = "1824006473F8" -- Double
 checkType(addr1)
 addr2 = "29AA1FEE10" -- Int
 checkType(addr2)
 addr3 = "3220047A352" -- Double >> 100.000000079162
 checkType(addr3)
 addr4 = "3220018B4EC" -- Int
 checkType(addr4)
 addr3 = "3220056F62B" -- float >> 1001.015625
 checkType(addr3)
 
 result:
 
 Element 0 type: vtDouble
 double: 100.000000000000 - 00 00 00 00 00 00 59 40
 Element 0 type: vtDword
 int: 1000 - E8 03 00 00
 Element 0 type: vtByte
 Other type: vtByte
 Element 0 type: vtDword
 int: 1000 - E8 03 00 00
 Element 0 type: vtByte
 Other type: vtByte
 _________________
 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Dark Byte Site Admin
 
  Reputation: 470 
 Joined: 09 May 2003
 Posts: 25807
 Location: The netherlands
 
 | 
			
				|  Posted: Wed Oct 01, 2025 11:18 pm    Post subject: |   |  
				| 
 |  
				| compilers generally never put floats in an address not dividable by at least 4 (8 or 16 is actually more common) so CE doesn't detect that as a float and just uses bytes to pad to the next alignment _________________
 
 Do not ask me about online cheats. I don't know any and wont help finding them.
 Like my help? Join me on Patreon so i can keep helping
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		|  |