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 


Bitwise operators in Lua?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
Balorn
Newbie cheater
Reputation: 0

Joined: 10 Apr 2012
Posts: 13

PostPosted: Sun May 27, 2012 10:49 pm    Post subject: Bitwise operators in Lua? Reply with quote

I know there must be some easy way to do this, but I can't find a way to do bitwise operations (specifically, I need to do a bitwise AND) in Lua.

Specifically, I have code like this (these are bits from different sections and functions in the script I'm making, but these are the parts that matter for this):
Code:
smask=65472 -- 0xFFC0
al=getAddressList()
sadr=addresslist_getMemoryRecordByDescription(al,"P1Status")
cstat=memoryrecord_getValue(sadr)

cstat=SomehowDoBitwiseAND(cstat,smask) -- How do I do this?

memoryrecord_setValue(sadr,cstat)

Sure, I suppose I could make a function that "unrolled" cstat into an array of bits I could manipulate, but there must be some easier way to do this.

(If anyone's curious, I'm trying to make code that clears "bad" status effects without affecting "good" status effects in an RPG, and the game stores each character's status at one address with each bit representing a different effect: 0x01=poison, 0x02=sleep, 0x04=paralysis and so on, but 0x40 and up are buffs...)
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

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

PostPosted: Mon May 28, 2012 2:09 am    Post subject: Reply with quote

Not as far as I know.
You could write a lua extension like luasock, or find one (you need to compile manually with ce's lua header files)
or write a ce plugin that registers these functions to lua

_________________
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
Balorn
Newbie cheater
Reputation: 0

Joined: 10 Apr 2012
Posts: 13

PostPosted: Mon May 28, 2012 3:01 am    Post subject: Reply with quote

Hm, would it be possible to do something with autoAssemble()? I've looked a bit at CE's assembler and it seems to focus on replacing a game's code with something else, but it seems it ought to be possible to just do an AND operation, either on a Lua variable or an address referenced in the cheat table. I've tried a couple things but haven't been able to get it to do what I need... or anything, really, without trying to inject code into the target app, which I really don't want to try to do for something like this.

Edit:
Well, I gave up and just wrote a function to do it in Lua. While doing so, I also found it seems to be missing a Modulo function, so on top of everything I had to use a string function to search for a decimal point after dividing by two... anyway, this is probably horribly inefficient, but here's what I wrote if anyone's curious. And believe me, I'd love to scrap it and just put in a simple bitwise AND instead.
Code:
function unroll16(a)
  local i
  local rem,res=a,{}
  for i=1,16 do
    if string.find(tostring(rem/2),"%.") then
      res[i]=true
      rem=(rem-1)/2
    else
      res[i]=false
      rem=rem/2
    end
  end
  return res
end

function rollup16(a)
  local res,p=0,1
  local i
  for i=1,16 do
    if a[i] then
      res=res+p
    end
    p=p*2
  end
  return res
end

function And16(x,y)
  local i
  local a,b,c=unroll16(x),unroll16(y),{}
  for i=1,16 do
    c[i]=a[i] and b[i]
  end
  return rollup16(c)
end
If I were forced to use this in something that was more time-restrictive (undoing status ailments every second or so is no problem), I'd probably combine these functions so it did it all in one loop, but this way is easy to read and would require minimal effort to add other bit-fiddling functions to, so I probably won't bother to redo it, at least for now.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

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

PostPosted: Mon May 28, 2012 7:44 am    Post subject: Reply with quote

while you should be able to use autoAssemble with CE as target, I won't work because I didn't export the function to hook raw addresses as functions to lua

When I get time I'll see about posting a plugin that adds this

_________________
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
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Mon May 28, 2012 8:04 am    Post subject: Reply with quote

Dark Byte wrote:
while you should be able to use autoAssemble with CE as target, I won't work because I didn't export the function to hook raw addresses as functions to lua

When I get time I'll see about posting a plugin that adds this


The latest version of Lua has Bitwise operators added to it.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Dark Byte
Site Admin
Reputation: 457

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

PostPosted: Mon May 28, 2012 8:07 am    Post subject: Reply with quote

I know, but there wasn't an lnum patch out before 6.2 was released (doesn't look like there is going to be one out when 6.3 gets released either...)
The 64-bit value thing is kinda important to me since I do intend on using the lua interface to mess with kernelmode memory from time to time

_________________
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
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Mon May 28, 2012 8:16 am    Post subject: Reply with quote

Ah, in that case you can find a bitwise lib for Lua 5.1/5.2 here:
http://bitop.luajit.org/

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Balorn
Newbie cheater
Reputation: 0

Joined: 10 Apr 2012
Posts: 13

PostPosted: Mon May 28, 2012 11:19 am    Post subject: Reply with quote

I just noticed something else about CE and Lua while playing around with making my (horribly inefficient) bit functions more generic.

Lua, only having a type for signed floating point numbrs, loses accuracy once it gets over 2^63-1, or less if a fraction is involved (for example, if you divide by 2 to see if the least significant bit is set, as I did in those functions).

CE's functions to read and write values use strings, though, so that's OK... unless you want to do math on them, not just set them. And once Lua starts changing a number's string representation to scientific notation, you can't write it back to CE unless you lower it back down to not need it.

I wrote the following as a test:
Code:
al=getAddressList()
mr=addresslist_getMemoryRecordByDescription(al,"Test8ByteInt")
print(testVal.." will be used for testing")
memoryrecord_setValue(mr,testVal)
v=memoryrecord_getValue(mr)
print(v.." was read as "..type(v))
vNum=tonumber(v)
print(vNum.." is that as a number")
vDec=vNum-1
print(vDec.." is that minus one")
if (vNum==vDec) then
  print("Accuracy was lost")
else
  print("Accuracy is OK internally")
end
vHalf=vNum/2
print(vHalf.." is half of it")
memoryrecord_setValue(mr,vHalf)
vHalfRead=memoryrecord_getValue(mr)
print(vHalfRead.." is what is read after writing "..vHalf)

If testVal is "9223372036854775806" (2^63-2), I get this:
9223372036854775806 will be used for testing
9223372036854775806 was read as string
9223372036854775806 is that as a number
9223372036854775805 is that minus one
Accuracy is OK internally
4611686018427387903 is half of it
4611686018427387903 is what is read after writing 4611686018427387903


If testVal is "9223372036854775807" (2^63-1) though (or any odd number approaching it), I run into a problem if I divide by 2:
9223372036854775807 will be used for testing
9223372036854775807 was read as string
9223372036854775807 is that as a number
9223372036854775806 is that minus one
Accuracy is OK internally
4.6116860184274e+018 is half of it
9223372036854775807 is what is read after writing 4.6116860184274e+018

Note that the value didn't get set, as CE can't write "4.6116860184274e+018" to an 8-byte integer (though 4611686018427400000 would still fit within it, even if accuracy was lost)

And if testVal is "9223372036854775808" (2^63) or higher, then it just gets worse:
9223372036854775808 will be used for testing
9223372036854775808 was read as string
9.2233720368548e+018 is that as a number
9.2233720368548e+018 is that minus one
Accuracy was lost
4.6116860184274e+018 is half of it
9223372036854775808 is what is read after writing 4.6116860184274e+018


Yes, I know this isn't something that's likely to come up often at all. But it's something people should be aware of.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

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

PostPosted: Mon May 28, 2012 12:35 pm    Post subject: Reply with quote

It has a few bugs yes.
most likely in the memoryrecord interface and due to the string part (values are strings in the addresslist, not real numbers)

Anyhow, when just coding in lua , defining a value as 0x8000000000000000 instead of 9223372036854775808 works better

_________________
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
Balorn
Newbie cheater
Reputation: 0

Joined: 10 Apr 2012
Posts: 13

PostPosted: Tue May 29, 2012 5:36 pm    Post subject: Reply with quote

If anyone wants some bitwise operations in the meantime, here's what I came up with in more generic form. They're fully reliable up to around 40ish bits, but it would be best to split anything above 32 into segments to be on the safe side.

I've only included AND here, but if you want OR or XOR or whatever just change the operation in the middle of that function.

And again, these are probably horribly inefficient, so I don't know if they'd work well in a timer that goes off frequently, especially if you stick them in a loop and have them run multiple times per tick. Me, I just put them on a "clear bad status ailments" button I click manually.

Still, better than nothing I suppose.

To use, just call bitAnd with the two numbers and how many bits it is. For example "newStatus=bitAnd(currentStatus,statusMask,16)" for a 2-byte value.

Code:
function unroll(a,bits)
  local i
  local rem,res=a,{}
  for i=1,bits do
    if string.find(tostring(rem/2),"%.") then
      res[i]=true
      rem=(rem-1)/2
    else
      res[i]=false
      rem=rem/2
    end
  end
  return res
end

function rollup(a,bits)
  local res,p=0,1
  local i
  for i=1,bits do
    if a[i] then
      res=res+p
    end
    p=p*2
  end
  return(res)
end

function bitAnd(x,y,bits)
  local i
  local a,b,c=unroll(x,bits),unroll(y,bits),{}
  for i=1,bits do
    c[i]=a[i] and b[i]
  end
  return rollup(c,bits)
end
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 218

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sat Jun 02, 2012 2:10 pm    Post subject: Reply with quote

@Balorn, do you have CE source and Lazarus installed?

You can add your own functions and compile it.

For example:
Code:
function dobitwiseAND(L: PLua_State): integer; cdecl;
var
  parameters: Qword;
  v: Qword;
begin
  result:=0;
  try
    parameters:=lua_gettop(L);
    if parameters=2 then
    begin
      v:=lua_tointeger(L,-1) and lua_tointeger(L,-2);

     lua_pop(L, parameters);
      lua_pushinteger(L,v);
      result:=1;
    end;
  except
    result:=0;
    lua_pop(L, lua_gettop(L));
  end;
end;

(...)
(...)

lua_register(LuaVM, 'dobitwiseAND', dobitwiseAND);


Of course, I made it very quickly without thorough tests.



My lua code (I got "Good"):
Code:
val1 = 28
val2 = 21
result = dobitwiseAND( val1 , val2 )
expectedresult = 20

if (expectedresult == result) then
  print('Good')
else
  print('Wrong')
end


If you want, I can upload cheatengine-i386.exe with dobitwiseAND dobitwiseOR and dobitwiseXOR functions.
Code:

val1 = '28'
val2 = '21'

result = dobitwiseAND( val1 , val2 )
print(result) -- gives 20

result = dobitwiseOR( val1 , val2 )
print(result) -- gives 29

result = dobitwiseXOR( val1 , val2 )
print(result) -- gives 9

_________________


Last edited by mgr.inz.Player on Sat Jun 02, 2012 2:52 pm; edited 2 times in total
Back to top
View user's profile Send private message MSN Messenger
Dark Byte
Site Admin
Reputation: 457

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

PostPosted: Sat Jun 02, 2012 2:19 pm    Post subject: Reply with quote

And as I said, you can also just do it as a plugin since the lua state is exported
_________________
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
mgr.inz.Player
I post too much
Reputation: 218

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sat Jun 02, 2012 7:18 pm    Post subject: Reply with quote

Plugin:
http://dl.dropbox.com/u/63264075/bitwiseLUAoperations.dll


code:
val1 = 0x7fffffffffffffff
val2 = 0x7ffffffffffffffe

print(dobitwiseAND(val1,val2))
print(dobitwiseOR(val1,val2))
print(dobitwiseXOR(val1,val2))

gives:
9223372036854775806
9223372036854775807
1

_________________
Back to top
View user's profile Send private message MSN Messenger
Dark Byte
Site Admin
Reputation: 457

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

PostPosted: Sat Jun 02, 2012 7:32 pm    Post subject: Reply with quote

post the source as well. I'll compile it.

according to http://forum.cheatengine.org/viewtopic.php?p=5348418&highlight=#5348418 the topic starter makes use of 64-bit

_________________
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
mgr.inz.Player
I post too much
Reputation: 218

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sat Jun 02, 2012 7:39 pm    Post subject: Reply with quote

OK, one minute...

Source: http://dl.dropbox.com/u/63264075/bitwiseLUAoperations.rar

_________________
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
Goto page 1, 2  Next
Page 1 of 2

 
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