|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Fri Nov 09, 2012 10:33 am Post subject: "Custom beep" for CETRAINER Trainer |
|
|
Sun Nov 11, 2012 4:40:06; edited 11 times in total
OK, we already have our trainer as CT file. Everything works. And we want custom Beep sound.
Your current LUA script looks like this:
Code: | --TRAINERGENERATORSTART--
(...)
strings_add(getAutoAttachList(), "gameprocessname.exe")
gBeepOnAction=true
form_show(CETrainer)
function AboutClick()
showMessage(gAboutText)
end
gAboutText=[[TEXT]]
function CloseClick()
closeCE()
return caFree --onClick doesn't care, but onClose would like a result
end
function onOpenProcess(processid)
xmplayer_stop()
(...)or something(...)
end
--TRAINERGENERATORSTOP-- |
What to do:
1) add WAV file to table, name it "CustomBeep.wav" (better use 22050Hz), you must know its size.
2) replace all beep() with CustomBeep.Play()
3) comment out those (place -- at the beginning of line):
- strings_add(getAutoAttachList(), "gameprocessname.exe")
- whole onOpenProcess function (if you have one)
4) add this at the end of LUA script:
Code: | CustomBeep =
{
WINMMAndWaveFileLoaded = false,
Play = function ()
if not CustomBeep.WINMMAndWaveFileLoaded then return end
autoAssemble([[createthread([400500])]],true) -- it's for CE process, use LOCAL
end,
Prepare = function ()
openProcess('cheatengine-x86_64.exe')
openProcess('cheatengine-i386.exe')
-- now we attached to CE itself
local callingConvention = ''
if cheatEngineIs64Bit() then
callingConvention =
[[push rbp
mov rbp,rsp
sub rsp,30
mov r8d,5
mov rdx,0
mov rcx,MemoryForWave
call winmm.PlaySoundA
leave
ret]]
else
callingConvention =
[[push 5
push 0
push MemoryForWave
call winmm.PlaySoundA
ret]]
end
local AAScript =
[[loadlibrary(winmm.dll)
alloc(CodePlaySound,]]..(CustomBeep.WaveFileSize+100)..[[)
label(MemoryForWave)
CodePlaySound+40:
MemoryForWave:
CodePlaySound:
]]..callingConvention..[[
400500:
dd CodePlaySound
dd 0
dd MemoryForWave
dd 0]]
if not autoAssemble(AAScript) then return end
local filename = os.getenv("TEMP")..'\\CustomBeep.wav'
tablefile_saveToFile(findTableFile("CustomBeep.wav"),filename)
readRegionFromFile(filename,readInteger(0x400508))
os.remove(filename)
CustomBeep.WINMMAndWaveFileLoaded = true
end,
AttachList = {},
AttachTimer = nil,
AttachTimerOnTimer = function (timer)
for i=1,#CustomBeep.AttachList do -- go through process names
if openProcess(CustomBeep.AttachList[i]) then -- check if process opened successfully
object_destroy(CustomBeep.AttachTimer) -- destroy and nil timer
CustomBeep.AttachTimer = nil
CustomBeep.OnOpenProcess() -- trigger OnOpenProcess
break
end
end
end,
AttachTo = function (processName)
table.insert(CustomBeep.AttachList,processName)
if CustomBeep.AttachTimer == nil then
CustomBeep.AttachTimer = createTimer(nil,false)
timer_setInterval(CustomBeep.AttachTimer,1000)
timer_onTimer(CustomBeep.AttachTimer,CustomBeep.AttachTimerOnTimer)
timer_setEnabled(CustomBeep.AttachTimer,true)
end
end
}
|
5) Add this at the end
Code: | CustomBeep.WaveFileSize = 100000
CustomBeep.Prepare()
CustomBeep.AttachTo("gameprocessname.exe")
function CustomBeep.OnOpenProcess (processid)
end
|
Use your wav file size.
If you want, you can use AttachTo few times for other exe names.
If you have some code inside original onOpenProcess(), paste this code inside CustomBeep.OnOpenProcess function
6) for better visual effect move form_show(CETrainer) at the very end
7) Save your current CT file as CETRAINER
Note:
if you see bugs, typos or you have questions - let me know.
_________________
Last edited by mgr.inz.Player on Sat Nov 10, 2012 9:40 pm; edited 12 times in total |
|
Back to top |
|
|
Csimbi I post too much Reputation: 94
Joined: 14 Jul 2007 Posts: 3110
|
Posted: Fri Nov 09, 2012 11:54 am Post subject: |
|
|
Well, the first thing I have to say: that idea is not new, but it's great.
I've been using audio feedback in my TMK trainers (a long time ago) to give feedback that a hotkey was pressed indeed. There would be more possibilities in CE.
A few thoughts.
I am guessing that people who add custom sounds will want to have a simple way to:
- add any number of waveforms
- play them from their scripts.
So I wonder if it would be better to create an array of ID and string pairs (ID: number, string: waveform's name), and expose a function like:
play(12, 1) -- play track 12, play once (not repeat)
play(999, 1) -- play track 999, once; oops, missing -> skip
play(2, 0) -- play track 2, play forever (repeat indefinitely) <- I am going to have this one as I don't like background music on trainers.
There could be other enhancements:
- which channel to use (left, right, both)
- localization
- play a chain of tracks (i.e., play track 12, when finished, play 10, when finished, play track 4)
- add Vorbis Audio (OGG) format, too (compressed, no licensing issues for compression) to minimize table/trainer size.
In any case, the first step is to add tracks to a cheat table somehow. Perhaps via the "Table" menu or via a new tab under "Table extras". I am guessing they'll get their IDs at that point - numbering them with a +1 increment, starting from 0. Then, we'd need an AA and a LUA function to actually play the track. (Yes, I'd like to see it in AA, too.)
Saving to the XML file is easy with BASE64 encoding - however it will increase the size of the tables significantly, so I wonder if it should be done somewhat differently. I can think of two ways:
No table update; the audio tracks are simple named like the cheat table and are stored separately. I.e. table.ct, table.ct.0.wav, table.ct.1.ogg, etc.
With table update; the index table is added to the cheat table, and each entry contains the name of the file (without path) and the files are stored at the same place as the cheat table so CE can access them. I.e. table.ct, activated.wav, disabled.ogg, etc.
In case of trainers, the external audio tracks would need to be added to the executable as resources.
I don't think I can help with coding all that, but you sure have my endorsement.
|
|
Back to top |
|
|
rockymark092 How do I cheat? Reputation: 0
Joined: 10 Nov 2012 Posts: 1
|
Posted: Sat Nov 10, 2012 5:34 am Post subject: |
|
|
Nice Post
_________________
rocky |
|
Back to top |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sat Nov 10, 2012 6:31 am Post subject: |
|
|
I made cetrainer with this custom beep and I got feedback:
"it appear that the "trainer" instantly close after the first use"
I assume it closes/crash just after CustomBeep() function first usage. Don't know why. For me it works every time - I have winxp32bit and I'm using cheatengine-i386.exe. Maybe it doesn't work for 64bit cheatengine version.
@Csimbi, I don't know if BASE64 is the best choice. Because when we save as cetrainer and choose "protect", whole XML file is compressed, and then protected with simple encryption.
What is more "compressible" - text with hex values or Base64 text ?
Sound tracks for trainer? Really?
But yes, OGG, it would be great. I think we can add some DLL to cheat table. Created cetrainer should do this (lua script): save this DLL to disk (temp folder), then import this DLL to CE process.
@DB,
we have readBytesLocal, readIntegerLocal, ....., readStringLocal, and write____Local, getAddress with optional local and autoAssemble with optional targetself
But we don't have readRegionFromFile with optional local/targetself. This is why I have to attach CE to itself.
I know I can use ..., push filename, call PlaySoundA. But I want to use sound loaded in memory.
CheatEngine (32 and 64 bit) is always loaded into 0x0400000 ?
_________________
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25291 Location: The netherlands
|
Posted: Sat Nov 10, 2012 6:57 am Post subject: |
|
|
Have you tried the loadbinary aa command?
Loadbinary(address, filename)
And yes, the base addresses for both 32 and 64 are hardcoded to 00400000
P.s: I found that editing near the mz header sometimes does have strange effects. I usually use 00400500
About the crashes: it won't work in 64-bit ce, as function calling is different.
What you could do of course is execute the play from inside the target game
_________________
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 |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sat Nov 10, 2012 8:59 am Post subject: |
|
|
Just installed win7 again
First change I must do is:
400020:
dd CodePlaySound
dd MemoryForWave
must be:
400020:
dd CodePlaySound
dd 0
dd MemoryForWave
dd 0
and use this
readRegionFromFile(filename, readInteger("400028"))
(instead 400024)
Edit:
this doesn't work, "access violation". Don't know why, there are three push, one call qword ptr, one jump and ret at the end
Code: | 03AF0000 - 6A 05 - push 05
03AF0002 - 6A 00 - push 00
03AF0004 - 68 4000AF03 - push 03AF0040 : ["RIFF?"]
03AF0009 - FF 15 02000000 - call qword ptr [03AF0011] ->winmm.Ordinal2
03AF000F - EB 08 - jmp 03AF0019
03AF0011 - 10 2F - adc [rdi],ch
03AF0013 - F6 FA - idiv dl
03AF0015 - FE 07 - inc byte ptr [rdi]
03AF0017 - 00 00 - add [rax],al
03AF0019 - C3 - ret |
Probably I have to use RCX, RDX and etc.
_________________
|
|
Back to top |
|
|
Bady Newbie cheater Reputation: 0
Joined: 23 Sep 2012 Posts: 10
|
Posted: Sat Nov 10, 2012 10:46 am Post subject: |
|
|
@mgr.inz.Player
Of course i can help you for this as tester ^^.
I'm on Windows 7 64 bits with an ATI card then no PhysX for me or at least the option is disabled in graphics if its usefull.
The problem is an instantly close of the trainer after the first use of blink and no sound was heard.
Dont hesitate next time, it's always a pleasure .
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25291 Location: The netherlands
|
Posted: Sat Nov 10, 2012 11:20 am Post subject: |
|
|
You will have to use registers yes
And allocate stackspace where the function you're going to call can store the register values if it wishes (Really, some 64-bit functions actually expect that the caller does that for them)
And make sure the stack keeps properly aligned
Again, i recommend doing funtion calls like that in the target with createThread and just use alloc/globalalloc
_________________
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 |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sat Nov 10, 2012 11:36 am Post subject: |
|
|
@Bady, thank you.
@Dark Byte
You suggest me to import winmm.dll into game process because:
- most games EXE's are 32 bit
- only simple push,..., call
But what if game has protections and we can use pointers only?
Probably we can't inject DLL file with injectDLL LUA command for those. Another thing: if something goes wrong, only trainer will crash, not the game.
MessageBoxA on 32 bit:
push 0
push offset szCaption
push offset szText
push 0
call MessageBoxA
MessageBoxA on 64 bit:
sub rsp, 28h
mov r9d, 0
lea r8, szCaption
lea rdx, szText
mov rcx, 0
call MessageBoxA
I'm wondering, how it looks for PlaySoundA
_________________
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25291 Location: The netherlands
|
Posted: Sat Nov 10, 2012 2:23 pm Post subject: |
|
|
32 bit is
Code: |
push 5
push 0
push MemoryForWave
call winmm.PlaySoundA
|
So for 64 bit it'd probably be
Code: |
Sub rsp,18. //3*8 and alignment is already correct (in short, rsp must be dividable by 16/0x10, and that happens with the last call)
Mov rcx, MemoryForWave
Mov rdx, 0
Mov r8,0
Call winmm.PlaySoundA
|
_________________
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 |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sat Nov 10, 2012 4:09 pm Post subject: |
|
|
Thanks DB. Yes it does work, partially at least.
I hear sound but then it crash with access violation or just hung.
I've downloaded lazarus for 64bit and used debugger.... this is what I've got:
And it works fully.
Code: | push rbp
mov rbp,rsp
sub rsp,30
mov r8d,5
mov rdx,0
mov rcx,MemoryForWave
call winmm.PlaySoundA
leave
ret |
looks like we need those "push rbp; mov rbp,rsp" at the beginning and leave before ret. And sub rsp,30.
Final modification:
Code: | if cheatEngineIs64Bit() then
callingConvention =
[[push rbp
mov rbp,rsp
sub rsp,30
mov r8d,5
mov rdx,0
mov rcx,MemoryForWave
call winmm.PlaySoundA
leave
ret]]
else
callingConvention =
[[push 5
push 0
push MemoryForWave
call winmm.PlaySoundA
ret]]
end |
_________________
|
|
Back to top |
|
|
Csimbi I post too much Reputation: 94
Joined: 14 Jul 2007 Posts: 3110
|
Posted: Sat Nov 10, 2012 4:26 pm Post subject: |
|
|
mgr.inz.Player wrote: |
@Csimbi, I don't know if BASE64 is the best choice. Because when we save as cetrainer and choose "protect", whole XML file is compressed, and then protected with simple encryption. |
By Hex encoding you mean simply changing binary to its hex text representation and not BinHex, right? That's what I assumed for now because BinHex is Mac-specific.
Hex encoding uses 16 ASCII characters and implies an increase of 100% (in practice, every single by becomes two).
BASE64 uses 64 ASCII characters and and implies an increase of at least 33% (8 bits becomes approx. 11 bits. and there's padding).
mgr.inz.Player wrote: | What is more "compressible" - text with hex values or Base64 text ? |
Typically, one never compresses that data, rather, removes the encoding and includes the binary format instead.
I understand you'd want to embed and XML file direcly in the executable, and you'd want to compress it.
I'd normally recommend using binary XML format instead - you can't beat that with any compression, however that's would mean a lot of implemenation effort, so I can see why simple compression zip or zlib might be preferred.
Since HEX encoding uses most of the time the same characters, the chances for repeating patterns is much higher. Ergo, it will appear to be compressing better. However, you have a larger amount of data to start with, so I guess the increased ratio is more or less meaningless.
If you are to use compression, you better compress the data before BASE64 encoding. But, we have audio - either wav, ogg, mp3, whatever that are already hard to compress, so I wonder if it's worth it.
I ran some tests with TotalCommander's zip compressor (max compression), please find the results attached as a screenshot.
The input files are the wav files that come with win7x64sp1 - these are not compressed in their original form; wavs can contain compressed data, too.
I took the original file, BASE64 encoded it and ZIPed up the BASE64 encoded file again.
Then, I tried ZIPing the original file, BASE64 encoding it and ZIPing up the BASE64 encoded file again.
Last, I tried MP3ing the original file (settings: vbr, 320k, high quality), BASE64 encoding it and ZIPing up the BASE64 encoded file again.
I put the stats into the table and added a few ratio calculations.
As you can see, the most significant reduction on the original file comes from MP3 compression (green colour); no surpise here, MP3 was specifically designed for that.
In the middle, you can see that BASE64 encoding is very much uniform; everything is about 137% here.
The light blue numbers on the right show you that you can use ZIP to compress the data again after BASE64 encoding.
The orange numbers show you the overall win, the ratio from WAV to the final (BASE64ed and then ZIPed).
The purple numbers show you the overall ratio from own source (adding BASE64 and ZIP to a WAV, a ZIP and an MP3 file). The first purple number is very interesting: it became smaller anyway!!!
The most important number is the initial compression - there's not much difference from there.
So, I'd go with MP3 or OGG (or, both).
Both of these are scalable depending on the quality.
OGG might yield better compression.
Opus audio would be the best (it is also an open format like Vorbis) - but it's brand new so there are no tools for that yet.
There are other binary to text encoding mechanisms (such as uuencode), but BASE64 was by far the most efficient and popular from what I've seen.
Instead of ZIP, one could use zlib. I did not run test on that however.
zlib is open and fast, so I guess you'll pick that anyway.
mgr.inz.Player wrote: | Sound tracks for trainer? Really? |
It's a figure of speech. We need to establish a terminology.
I usually call any audio with a unique ID a 'track'.
I hope this helps you make a good design.
Description: |
|
Filesize: |
36.53 KB |
Viewed: |
28065 Time(s) |
|
|
|
Back to top |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
|
Back to top |
|
|
Csimbi I post too much Reputation: 94
Joined: 14 Jul 2007 Posts: 3110
|
Posted: Sat Nov 10, 2012 8:09 pm Post subject: |
|
|
I don't have it installed, sorry...
|
|
Back to top |
|
|
Bady Newbie cheater Reputation: 0
Joined: 23 Sep 2012 Posts: 10
|
Posted: Sun Nov 11, 2012 9:00 am Post subject: |
|
|
Works perfectly and the sound is exactly appropriate and not annoying .
|
|
Back to top |
|
|
|
|
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
|
|