Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Get table of EFLAGS

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
GH*master
Expert Cheater
Reputation: 8

Joined: 10 Jan 2008
Posts: 159

PostPosted: Sun Jun 18, 2017 2:49 am    Post subject: Get table of EFLAGS Reply with quote

Code:
function to_BitsNew(num,bits)
  bits = bits or math.max(1, select(2, math.frexp(num)))
  local t = {}
  for b = bits, 1, -1 do
    t[b] = math.fmod(num, 2)
    num = math.floor((num - t[b]) / 2)
  end
  return t
end

function get_EFLAGS()
 
  local bitsTable = to_BitsNew(EFLAGS,32)
 
  local tableEFLAGS =
  {
    OF = bitsTable[21],
    DF = bitsTable[22],
    SF = bitsTable[25],
    ZF = bitsTable[26],
    AF = bitsTable[28],
    PF = bitsTable[30],
    CF = bitsTable[32]
  }
 
  return tableEFLAGS
end

local tableEFLAGS = get_EFLAGS()
for k,v in pairce(tableEFLAGS) do
 print(string.format('%s :'..'%s', k, v))
end



eflags3.png
 Description:
 Filesize:  49.49 KB
 Viewed:  7606 Time(s)

eflags3.png


Back to top
View user's profile Send private message
FreeER
Grandmaster Cheater Supreme
Reputation: 53

Joined: 09 Aug 2013
Posts: 1091

PostPosted: Sun Jun 18, 2017 7:31 am    Post subject: Reply with quote

Nice! Though I think you have a typo with pairce, shouldn't that be pairs or is that a function you've created? Otherwise it seems to work great except for the error when EFLAGS is nil (if you have not broken anywhere yet) Smile

a check and an additional return of debug_isBroken() would let the caller check if the flags are "current"/up-to-date or simply what was set on the last breakpoint (who knows when ago lol)

Code:
-- returns table of "bits" bits (defaults to log_2 of num) from num
function to_BitsNew(num,bits)
  bits = bits or math.max(1, select(2, math.frexp(num)))
  local t = {}
  for b = bits, 1, -1 do
    t[b] = math.fmod(num, 2)
    num = math.floor((num - t[b]) / 2)
  end
  return t
end

--[[
  returns nil (3 times) if EFLAGS is nil (debugger hasn't broken before)
  returns the table of OF, DF, SF, ZF, AF, PF, and CF (all status flags + DF),
       a bool to tell if the flags are up-to-date (currently just if the debugger is broken)
       and the intermediate bits table because we already did the work to get it...
]]
function get_EFLAGS()
  if not EFLAGS then return nil, nil, nil end
  local bitsTable = to_BitsNew(EFLAGS,32)

  local tableEFLAGS =
  {
    OF = bitsTable[21],
    DF = bitsTable[22],
    SF = bitsTable[25],
    ZF = bitsTable[26],
    AF = bitsTable[28],
    PF = bitsTable[30],
    CF = bitsTable[32]
  }

  return tableEFLAGS, debug_isBroken(), bitsTable
end

local tableEFLAGS, isUpdated, fullBitTable = get_EFLAGS()
print("Flags updated: " .. tostring(isUpdated))
if not tableEFLAGS then return end

for k,v in pairs(tableEFLAGS) do
 print(string.format('%s: %s', k, v))
end


While it's of course possible to simply assume the caller will check debug_isBorken on their own... some won't know about it unless told and also it allows you (or someone else) to come back later and improve that result (for instance, if you change the flags in the memory viewer the EFLAGS value doesn't update until you step/continue; I did try using debug_setContext to see if that would update it, no luck).


BTW, what was the point of format if you're going to concatenate the : anyways? Didn't even see that until I started messing with the output to check something Smile

edit: not sure if it'd be more useful to simply have something like this (obviously could be done without metatables but I felt like playing with them since I rarely do lol)
Code:
FLAGPOWS = {CFPOW=0, PFPOW=2, AFPOW=4, ZFPOW=6, SFPOW=7, TFPOW=8, IFPOW=9, DFPOW=10, OFPOW=11}
for k,v in pairs(FLAGPOWS) do FLAGPOWS[k] = math.pow(2,v) end
FLAGS = {}
FLAGSMT = {__index = function(table, index)
  iupper = index:upper()
  if iupper == "CURRENT" or iupper == "UPTODATE" then return debug_isBroken() end
  if not FLAGPOWS[iupper.."POW"] then error(string.format("%s is not a valid flag", iupper)) end
  debug_getContext(); return (bAnd(EFLAGS, FLAGPOWS[iupper.."POW"]) ~= 0)
end,
__tostring = function(table) for k,v in pairs(FLAGPOWS) do flag = k:sub(0,-4); print(string.format("%s: %s", flag, FLAGS[flag])) end end,
__newindex = function(table,index,value)
   mask = FLAGPOWS[index:upper().."POW"]; if value == 0 then EFLAGS = bAnd(EFLAGS, bNot(mask)) else EFLAGS = bOr(EFLAGS, mask) end
   debug_setContext(); --debug_updateGUI()
end}
setmetatable(FLAGS,FLAGSMT)

print(tostring(FLAGS))
FLAGS.of = 1
FLAGS.zf = 0
FLAGS.AF = 1
FLAGS.CF = 1
print("\n")
print(tostring(FLAGS.of))
print(tostring(FLAGS.ZF))
print(tostring(FLAGS.AF))
print("\n")
print(tostring(FLAGS))
--print(string.format("testing is %s", FLAGS.testing))
pcall(function() print(string.format("testing is %s", FLAGS.testing)) end)


edit2: to make use of the bitwise operators DB showed (also a couple fixes and a "feature"):

Code:
FLAGPOWS = {CFPOW=1<<0, PFPOW=1<<2, AFPOW=1<<4, ZFPOW=1<<6, SFPOW=1<<7, TFPOW=1<<8, IFPOW=1<<9, DFPOW=1<<10, OFPOW=1<<11}
FLAGS = {}
FLAGSMT = {__index = function(table, index)
  if type(index) == "string" then
    iupper = index:upper()
    if iupper == "CURRENT" or iupper == "UPTODATE" then return debug_isBroken() end
    debug_getContext() if not EFLAGS then return nil end
    if FLAGPOWS[iupper.."POW"] then return EFLAGS & FLAGPOWS[iupper.."POW"] ~= 0 end
  elseif type(index) == "number" and index >= 0 and index < 33 then
    debug_getContext(); return EFLAGS & 1<<math.floor(index) ~= 0
  else error(string.format("'%s' is not a valid flag", iupper)) end
end,
__tostring = function(table) print("current: "..tostring(FLAGS.current));
  for k,v in pairs(FLAGPOWS) do flag = k:sub(0,-4); print(string.format("%s: %s", flag, FLAGS[flag])) end end,
__newindex = function(table,index,value)   -- anyway to signal error other than error? hm....
   mask = FLAGPOWS[index:upper().."POW"]; if not EFLAGS then error("Could not set flag " .. tostring(index)) end
   if value == 0 then EFLAGS = EFLAGS & ~mask else EFLAGS = EFLAGS | mask end
   debug_setContext(); --debug_updateGUI()
end}
setmetatable(FLAGS,FLAGSMT)

FLAGS.af = 1
print('af = ' .. tostring(FLAGS[4]))
print(tostring(FLAGS))
--debug_updateGUI()


As DB showed most of this code is to let you use names.


Last edited by FreeER on Mon Jun 19, 2017 8:48 am; edited 1 time in total
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25284
Location: The netherlands

PostPosted: Mon Jun 19, 2017 4:11 am    Post subject: Reply with quote

here are some functions to get a specific bit and set a specific bit
Code:

function isBitSet(value,bitnr)
  return value & (1<<bitnr)~=0
end

function setBit(value,bitnr,state)
  local bm=1<<bitnr
  if state then
    return value | bm
  else
    return value & ~bm
  end
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
View user's profile Send private message MSN Messenger
GH*master
Expert Cheater
Reputation: 8

Joined: 10 Jan 2008
Posts: 159

PostPosted: Mon Jun 19, 2017 4:49 am    Post subject: Reply with quote

Many thanks Razz
Back to top
View user's profile Send private message
FreeER
Grandmaster Cheater Supreme
Reputation: 53

Joined: 09 Aug 2013
Posts: 1091

PostPosted: Mon Jun 19, 2017 8:52 am    Post subject: Reply with quote

@DB hm, does lua have bitwise operators or is that just CE? All I saw from google searches was libraries adding functions like bAnd etc.

Nice to know regardless, thanks Smile
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25284
Location: The netherlands

PostPosted: Mon Jun 19, 2017 9:06 am    Post subject: Reply with quote

ce 6.5.1 and later uses lua 5.3
it has built-in binary operators

_________________
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
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites