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 


Hacking Love2D

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
LuaWeaver
How do I cheat?
Reputation: 0

Joined: 16 Oct 2012
Posts: 4

PostPosted: Tue Apr 02, 2013 12:51 pm    Post subject: Hacking Love2D Reply with quote

Hello. If you didn't know already, Love2D is a game engine which uses the Lua programming language for the games. I'm interested in a couple of things that I've not discovered on my own-

1) Finding the location in memory of the function that is changing a value (I can find what changes it, but not the actual location of the function)

2) Taking that function and calling it (perhaps with different arguments)

and 3) Forcing the function to go to my own function.

If anyone would know how to do this, please tell me how I would achieve these goals (or just give me a gentle nudge in the direction I must go). Thanks in advance.

_________________
--LuaWeaver
Back to top
View user's profile Send private message
Gniarf
Grandmaster Cheater Supreme
Reputation: 43

Joined: 12 Mar 2012
Posts: 1285

PostPosted: Tue Apr 02, 2013 1:45 pm    Post subject: Re: Hacking Love2D Reply with quote

LuaWeaver wrote:
1) Finding the location in memory of the function that is changing a value (I can find what changes it, but not the actual location of the function)
With "find out what writes to..." you can find the instruction that writes to your variable, then scroll up in CE's memory viewer until you see several (4+) "int 3" or "nop". The function that wrote your variable begins at the first instruction that is not a "int 3" or "nop". However what you'll find that way is the assembly code of the lua interpreter/framework, so if you alter this you're going to disable -for example- all additions within your game -> not good.

If you want to find the lua function that ordered the lua framework to change your variable, well you're wasting your time because lua is a pseudo compiled language ie: when you give a text to lua it first "compiles" it into a pseudo-code and when you play, only the pseudo code is used. Compilation can occur in development studio before releasing, or each time you start the game, or each time you load a map/level/etc, and happens each time you type something in a lua console.

So if you where able to find the location in memory of the lua function that is changing a value, that would be its pseudo code, and the problem is that pseudo code -> text decompilers are still quite buggy as of 2013/04. They work well on laboratory test cases, but on real life scripts, duhhh...nope. They can give useful clues regarding how scripts are made (that information was critical when I hacked Krater), but don't expect to be able to recompile medium-sized and/or complex scripts.

All in all I'd advise banging your head on editing the text luas before the game loads them, if such texts are available.

LuaWeaver wrote:
and 3) Forcing the function to go to my own function.
That's is called lua hooking. I've never done it personally, but roughtly the idea is that you take a function like:
Code:
function foo()
  print("Bar")
end

and do a hook (replacement) like that:
Code:
OriginalFoo=foo
foo = function()
  print("foo is fubared !")
  -- OriginalFoo() --if you want to call the original code
end
If you've got access to a lua console within the game it's fairly easy, but if you don't, meh...

One crazy idea -definitely NOT for greenhorn hackers- would be to:
-compile your own application that uses lua. Open source luac (stands for lua compiler) should be enough.
-In its compiled code, find the assembly code of the function luaL_loadstring and copy it.
-Search for luaL_loadstring's code (signature) within your game.
-Hook luaL_loadstring or any other luaL_load* to get the value of the "Lua_State *L".
-Call luaL_loadstring with the proper arguments. Congratulation you just forcefully made yourself a lua console! Now you can do your lua hooking.
Back to top
View user's profile Send private message
LuaWeaver
How do I cheat?
Reputation: 0

Joined: 16 Oct 2012
Posts: 4

PostPosted: Tue Apr 02, 2013 2:06 pm    Post subject: Re: Hacking Love2D Reply with quote

Gniarf wrote:
One crazy idea -definitely NOT for greenhorn hackers- would be to:
-compile your own application that uses lua. Open source luac (stands for lua compiler) should be enough.
-In its compiled code, find the assembly code of the function luaL_loadstring and copy it.
-Search for luaL_loadstring's code (signature) within your game.
-Hook luaL_loadstring or any other luaL_load* to get the value of the "Lua_State *L".
-Call luaL_loadstring with the proper arguments. Congratulation you just forcefully made yourself a lua console! Now you can do your lua hooking.


Actually, forcing loadstring is one of my goals. However, I am relatively new to this - I'm very good at Lua, however. How would I properly identify luaL_loadstring within luac, and how would I get the Lua_State after that? Then, how would I call luaL_loadstring once more? If you'd kindly reply once more, it's be nice.

Thanks for your reply.

_________________
--LuaWeaver
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

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

PostPosted: Tue Apr 02, 2013 2:15 pm    Post subject: Reply with quote

Perhaps it might be of some help to know that the most common implementation of lua_gettop(lua_state*) has an aob of :"8b 4c 24 04 8b 41 08 2b 41 0c c1 f8 04 c3"
_________________
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
LuaWeaver
How do I cheat?
Reputation: 0

Joined: 16 Oct 2012
Posts: 4

PostPosted: Tue Apr 02, 2013 2:31 pm    Post subject: Reply with quote

Dark Byte wrote:
Perhaps it might be of some help to know that the most common implementation of lua_gettop(lua_state*) has an aob of :"8b 4c 24 04 8b 41 08 2b 41 0c c1 f8 04 c3"


I have no idea how I would use this, nor can I find a tutorial which will explain it. Mind helping?

_________________
--LuaWeaver
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 222

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

PostPosted: Tue Apr 02, 2013 4:08 pm    Post subject: Reply with quote

@DB, interesting. So, there is fancy way to do it with CE?

which opcode access lua_state? Or, is it EAX?

Code:
8B 4C 24 04           - mov ecx,[esp+04]
8B 41 08              - mov eax,[ecx+08]
2B 41 0C              - sub eax,[ecx+0C]
C1 F8 04              - sar eax,04
C3                    - ret


an example would be cool.



Even a simple one like this:
1) we launch CE, and execute this script:
Code:
playerStats = {}
playerStats.Health = 30

if timer~=nil then object_destroy(timer);timer=nil;end

timer = createTimer(nil,true)
timer.Interval = 1000
timer.OnTimer = function (sender)
                  if playerStats.Health >=100 then
                    sender.Enabled = false
                    showMessage('success')
                  end
                end


2) we launch second CE, attach to first CE, do aobscan. Then .....


then what? Attach debugger, set breakpoint at "ret". Store EAX. We get "lua_state" as EAX right?

Code:

(...)
lua_state_top = EAX
debug_continueFromBreakpoint(co_run)
(...)


Then what? We probably need some CE plugin which add registered function otherLua_doString.

something like this:
Code:
otherLua_doString(lua_state_top, 'playerStats.Health = 100')

_________________


Last edited by mgr.inz.Player on Tue Apr 02, 2013 4:55 pm; edited 1 time in total
Back to top
View user's profile Send private message MSN Messenger
Gniarf
Grandmaster Cheater Supreme
Reputation: 43

Joined: 12 Mar 2012
Posts: 1285

PostPosted: Tue Apr 02, 2013 4:27 pm    Post subject: Re: Hacking Love2D Reply with quote

LuaWeaver wrote:
How would I properly identify luaL_loadstring within luac
Compile luac in release mode with debug symbols, debug it (I mean run it under debugger supervision), right click on luaL_loadstring's definition in visual studio->show disassembly. Copy its address and watch it in CE to see the byte code, which should be useful for an aobscan.

LuaWeaver wrote:
and how would I get the Lua_State after that?
Find and hook any frequently used lua_*** function, and store its first argument.

LuaWeaver wrote:
Then, how would I call luaL_loadstring once more?
Use a pair of autoassembler scripts like those:
Code:
[enable]
//code locations
label(FrequentlyUsedLuaFunction_hook)
label(FrequentlyUsedLuaFunction_ReturnHere)
label(InjectedLuaConsole)
label(InjectedLuaConsole_InvalidLuaState)
//variables:
label(LuaStatePointer)
label(LuaCommandToRun)
//locate the functions
aobscan(FrequentlyUsedLuaFunction_aob,...find_those...)
aobscan(lua_loadstring, 8B 54 24 08 83 EC 08 8B C2 56 8D 70 01) //doesn't work on sfxt

alloc(MyCode,1024) //room for MyCode

FrequentlyUsedLuaFunction_aob:
 jmp FrequentlyUsedLuaFunction_hook
FrequentlyUsedLuaFunction_ReturnHere:


MyCode:
FrequentlyUsedLuaFunction_hook:
 push eax
 mov eax,dword [esp+8]
 mov dword [LuaStatePointer],eax
 pop eax
 //paste here the code you overworte at FrequentlyUsedLuaFunction_aob:
 /*...
 ...
 ...*/
jmp FrequentlyUsedLuaFunction_ReturnHere

InjectedLuaConsole:
 cmp dword [LuaStatePointer],0
 je InjectedLuaConsole_InvalidLuaState
  push LuaCommandToRun
  push dword [LuaStatePointer]
  call lua_loadstring
  add esp, 8             //lua_loadstring is a cdecl 2 argument function
 InjectedLuaConsole_InvalidLuaState:
ret
//variables
LuaStatePointer:
dd 0
LuaCommandToRun:
db 'print("fu**bar")'0

registersymbol(LuaCommandToRun) //add a string to your cheat table with address "LuaCommandToRun"
registersymbol(InjectedLuaConsole)


[disable]
dealloc(MyCode)
unregistersymbol(LuaCommandToRun)
unregistersymbol(InjectedLuaConsole)


And a second one to run the commands
Code:

[enable]
createthread(InjectedLuaConsole)
[disable]
createthread(InjectedLuaConsole)


Unfortunately I tested them on Street Figter x Tekken, but couldn't find lua_loadstring...Looks like that crazy idea doesn't work that easily after all.
Still it should work on games that use a separate lua5.1.dll.

mgr.inz.Player wrote:
then what? Attach debugger, set breakpoint at "ret". Store EAX. We get "lua_state" as EAX right?
Doubtful:
Code:
LUA_API int lua_gettop (lua_State *L) {
  return cast_int(L->top - L->base);
}
I think lua_gettop just returns part of the lua_State, which is a required input.

Last edited by Gniarf on Tue Apr 02, 2013 5:10 pm; edited 3 times in total
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 222

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

PostPosted: Tue Apr 02, 2013 4:52 pm    Post subject: Reply with quote

oops, I meant "we get top as EAX".

Anyway, here lua5.1 luaL_loadstring

Code:

lua5.1-32.luaL_loadstring    - 8B 54 24 08           - mov edx,[esp+08]
lua5.1-32.luaL_loadstring+4  - 83 EC 08              - sub esp,08
lua5.1-32.luaL_loadstring+7  - 8B C2                 - mov eax,edx
lua5.1-32.luaL_loadstring+9  - 56                    - push esi
lua5.1-32.luaL_loadstring+A  - 8D 70 01              - lea esi,[eax+01]
lua5.1-32.luaL_loadstring+D  - 8D 49 00              - lea ecx,[ecx+00]
lua5.1-32.luaL_loadstring+10 - 8A 08                 - mov cl,[eax]
lua5.1-32.luaL_loadstring+12 - 40                    - inc eax
lua5.1-32.luaL_loadstring+13 - 84 C9                 - test cl,cl
lua5.1-32.luaL_loadstring+15 - 75 F9                 - jne lua5.1-32.luaL_loadstring+10
lua5.1-32.luaL_loadstring+17 - 8B 4C 24 10           - mov ecx,[esp+10]
lua5.1-32.luaL_loadstring+1B - 2B C6                 - sub eax,esi
lua5.1-32.luaL_loadstring+1D - 52                    - push edx
lua5.1-32.luaL_loadstring+1E - 89 44 24 0C           - mov [esp+0C],eax
lua5.1-32.luaL_loadstring+22 - 8D 44 24 08           - lea eax,[esp+08]
lua5.1-32.luaL_loadstring+26 - 50                    - push eax
lua5.1-32.luaL_loadstring+27 - 68 70340010           - push lua5.1-32.luaL_loadfile+220
lua5.1-32.luaL_loadstring+2C - 51                    - push ecx
lua5.1-32.luaL_loadstring+2D - 89 54 24 14           - mov [esp+14],edx
lua5.1-32.luaL_loadstring+31 - E8 2AF0FFFF           - call lua5.1-32.lua_load
lua5.1-32.luaL_loadstring+36 - 83 C4 10              - add esp,10
lua5.1-32.luaL_loadstring+39 - 5E                    - pop esi
lua5.1-32.luaL_loadstring+3A - 83 C4 08              - add esp,08
lua5.1-32.luaL_loadstring+3D - C3                    - ret

_________________
Back to top
View user's profile Send private message MSN Messenger
Gniarf
Grandmaster Cheater Supreme
Reputation: 43

Joined: 12 Mar 2012
Posts: 1285

PostPosted: Tue Apr 02, 2013 5:03 pm    Post subject: Reply with quote

I'm probably missing something, but what do you want to do with the stack's top? As long as you've got the lua_State* you've got all you need to fire a luaL_loadstring, right?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

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

PostPosted: Tue Apr 02, 2013 5:07 pm    Post subject: Reply with quote

Quote:

Find and hook any frequently used lua_*** function, and store its first argument.

lua_gettop is one of the most often called ones

_________________
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: 222

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

PostPosted: Tue Apr 02, 2013 6:21 pm    Post subject: Reply with quote

@Dark Byte

mov ecx,[esp+04]
mov eax,[ecx+08]
sub eax,[ecx+0C]
so, Lua_state is in ECX?


Could you test this table? It is for 32bit cheatengine. After loading CT file we allow lua script to launch. CheatEngine should attach to itself. There is timer, ontimer checks if "health" is bigger or equal to 100.

1) tick "script (lua_state hijack)" script
2) set "set to 1 to enable" to 1

No effect. What's wrong?



It doesn't crash (this is a good sign I think).



hijackLua.ct
 Description:

Download
 Filename:  hijackLua.ct
 Filesize:  2.17 KB
 Downloaded:  822 Time(s)


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

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

PostPosted: Tue Apr 02, 2013 7:06 pm    Post subject: Reply with quote

your aa script only loads the script, but it does not execute the function

luaL_loadstring pushes a function on the lua stack that you must execute with lua_call/lua_pcall

check lua_dostring in luahandler.pas

_________________
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: 222

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

PostPosted: Tue Apr 02, 2013 7:32 pm    Post subject: Reply with quote

Got this. Made like this:

Code:
push command
push ecx
call lua5.1-32.luaL_loadstring
add esp,08

// and then

push 0
push -1
push 0
push ecx
call lua5.1-32.lua_pcall
add esp,10


I think we can finally make any cheat for any Lua based game (single player game), of course if we know table names and etc. I will try this tomorrow with "Don't Starve" as target.



hijackLua.ct
 Description:
Now converted to CE6.2
(previously CE6.2+)

Download
 Filename:  hijackLua.ct
 Filesize:  2.29 KB
 Downloaded:  846 Time(s)


_________________


Last edited by mgr.inz.Player on Tue Apr 30, 2013 6:42 pm; edited 2 times in total
Back to top
View user's profile Send private message MSN Messenger
Gniarf
Grandmaster Cheater Supreme
Reputation: 43

Joined: 12 Mar 2012
Posts: 1285

PostPosted: Tue Apr 02, 2013 7:49 pm    Post subject: Reply with quote

First thing first: apologies for the mess up, when I saw loadstring I jumped the gun and assumed it automatically ran it, my bad.

...As a fixup I made this:
The lua script is adapted from mgr.inz.Player's.
note: you need to run one lua command after activating the hook for the run script to work.



hijackLua3.ct
 Description:

Download
 Filename:  hijackLua3.ct
 Filesize:  2.98 KB
 Downloaded:  956 Time(s)

Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 222

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

PostPosted: Tue Apr 30, 2013 6:34 pm    Post subject: Reply with quote

The problem is that "Don't Starve" doesn't have symbols
and some functions signatures are different than "CE Lua"'s signatures.
But, I found them Very Happy

OK, now I can use this like this:
Code:
myLuaCommand = 'local a = 2 + 3 * 4'
writeString('ourCommands', myLuaCommand)
writeInteger(getAddress('ourCommands')+#myLuaCommand,0)        -- string must end with \0
writeInteger('doit',1)







This is how I made Don't Starve injected Lua console:
Code:
alloc(newmem,2048)
label(exit)
aobscan(gettopAOB,8B4C24048B41082B410CC1F804C3)
aobscan(loadstringAOB,8b54240883ec088bc2)
aobscan(pcallAOB,8B44241083EC0856)

label(gettopCODE)
registersymbol(gettopCODE)

label(doit)
registersymbol(doit)

label(ourCommands)
registersymbol(ourCommands)

newmem:
cmp dword ptr [doit],0
je short exit
mov dword ptr [doit],0

mov ecx,[esp+04]
push ourCommands
push ecx
call loadstringAOB
add esp,08

mov ecx,[esp+04]
push 0
push -1
push 0
push ecx
call pcallAOB
add esp,10

exit:
mov ecx,[esp+04] // orig
mov eax,[ecx+08] // orig
sub eax,[ecx+0C] // orig
sar eax,04       // orig
ret              // orig

doit:
dd 00
ourCommands:
db 0

gettopAOB+a:
gettopCODE:
jmp newmem


my previous CT file (so we hack Lua used in CE itself, for learning purposes) updated too.

_________________
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 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