 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Affly Cheater
Reputation: 1
Joined: 29 Sep 2013 Posts: 42
|
Posted: Wed Dec 28, 2016 9:19 am Post subject: Multi-address adder |
|
|
I keep running into an annoyance given that I generally enjoy games where you have inventories to manage. Usually you can bypass this using some "selected item count" but if you want an item you don't currently have you're screwed.
Generally you find a value, dissect the structure, find a pointer and from that you have pointers to every possible item once you test/identify them.
Thanks to the wonderful people here I had some Lua scripts that would add these pointers in mass so I would get to testing them but now I lost them to a HDD failure and have to remake them (surprise surprise, I have no idea how I made them work).
So my suggestion: expand on the "add address manually" button to be able to add multiple addresses with a defined interval between.
Quick mock-up and example:
http://puu.sh/t3Crg/a5a70ca436.png
This would add 200 pointers to the list, first would be [["game.dll"+0000xx]+320]+48, second would be [["game.dll"+0000xx]+320]+A8 (48+60), third [["game.dll"+0000xx]+320]+108, etc.
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Wed Dec 28, 2016 7:29 pm Post subject: |
|
|
Code: | local al = getAddressList()
local base = al.createMemoryRecord()
base.setDescription("Base Address")
base.Type = vtString
base.String.Size = 0
base.Address = "game.exe+00001234"
base.OffsetCount = 2
base.Offset[0] = 0
base.Offset[1] = 0x320
for i = 0, 20 do
local address = string.format("+%X", i * 0x60 + 0x48)
local offset = al.createMemoryRecord()
offset.Type = vtDword
offset.Address = address
offset.Description = address
offset.appendToEntry(base)
end |
|
|
Back to top |
|
 |
Affly Cheater
Reputation: 1
Joined: 29 Sep 2013 Posts: 42
|
Posted: Thu Dec 29, 2016 7:45 am Post subject: |
|
|
I ended up redoing something like that to populate the cheat table... Except a few hours later I found some CE functionality I didn't know about that reduced the work required massively and also will make the table much easier to fix in case something breaks... Learn something new every day I guess.
|
|
Back to top |
|
 |
condamor Newbie cheater
Reputation: 0
Joined: 02 Jan 2017 Posts: 10
|
Posted: Mon Jan 02, 2017 4:59 am Post subject: |
|
|
Could either of you help me please?
Affly, in coding communities it's somewhat a norm to post your own solution to your questions if you come up with them, so people like me can benefit too [8
Zanzer, I'm trying to dissect what you have posted along with the few results I get from google.
Here's what I'm working with. It's pretty much all there, minus the fact that I mostly have no idea how to manipulate the things I am trying to manipulate.
I'm trying to get this to work with address offsets. And I'm not even sure I'm handling everything the right way.
Code: | function AddCheatTableRecord(_description, _address, _offset, _type, _length)
local CEAddressList = getAddressList()
local NewRecord = CEAddressList.createMemoryRecord();
NewRecord.Description = _description
NewRecord.Address = _address
if _offset ~= nil then
-- = _offset
NewRecord.OffsetCount = 1
NewRecord.Offset[0] = _offset
end
if _type == "string" then
NewRecord.Type = vtString
if _length ~= nil then
NewRecord.String.Size = _length
end
--NewRecord.String.Unicode=true
elseif _type == "binary" then
NewRecord.Type = vtBinary
elseif _type == "double" then
NewRecord.Type = vtDouble
elseif _type == "float" then
NewRecord.Type = vtSingle
elseif _type == "array of bytes" then
NewRecord.Type = vtByteArray
elseif _type == "byte" then
NewRecord.Type = vtByte
elseif _type == "2 bytes" then
NewRecord.Type = vtWord
elseif _type == "4 bytes" then
NewRecord.Type = vtDword
elseif _type == "8 bytes" then
NewRecord.Type = vtQword
end
local ParentRecord = CEAddressList.getMemoryRecordByDescription('Player Attributes')
if ParentRecord ~= nil then NewRecord.appendToEntry(ParentRecord) end
end |
P.S.
How do people usually figure out how to work undocumented things? lol
P.P.S.
I see I can't post twice in a row, so...
Oops! Totally thought I had my results here.
Typically when I handle addresses in my code, it's in the form of "[pcsx2-r3878.exe+003FDCA0]+908". When I passed that as the address (with slightly different code) it just ended up in the address field, all poorly formatted and no offset
AddCheatTableRecord("Test", "003FDCA0", nil, "string", 50)
AddCheatTableRecord("Test2", "003FDCA0", nil, "float")
AddCheatTableRecord("Test3", "003FDCA0", nil, "4 bytes")
AddCheatTableRecord("Test0", "003FDCA0", 908, "string", 50)
resulted in:
Code: | <?xml version="1.0" encoding="utf-8"?>
<CheatTable>
<CheatEntries>
<CheatEntry>
<ID>5405</ID>
<Description>"Test"</Description>
<LastState Activated="0" RealAddress="003FDCA0"/>
<Color>80000008</Color>
<VariableType>String</VariableType>
<Length>50</Length>
<Unicode>0</Unicode>
<ZeroTerminate>1</ZeroTerminate>
<Address>003FDCA0</Address>
</CheatEntry>
<CheatEntry>
<ID>5406</ID>
<Description>"Test2"</Description>
<LastState Value="??" Activated="0" RealAddress="003FDCA0"/>
<Color>80000008</Color>
<VariableType>Float</VariableType>
<Address>003FDCA0</Address>
</CheatEntry>
<CheatEntry>
<ID>5407</ID>
<Description>"Test3"</Description>
<LastState Value="??" Activated="0" RealAddress="003FDCA0"/>
<Color>80000008</Color>
<VariableType>4 Bytes</VariableType>
<Address>003FDCA0</Address>
</CheatEntry>
<CheatEntry>
<ID>5408</ID>
<Description>"Test0"</Description>
<LastState Activated="0" RealAddress="00000000"/>
<Color>80000008</Color>
<VariableType>String</VariableType>
<Length>50</Length>
<Unicode>0</Unicode>
<ZeroTerminate>1</ZeroTerminate>
<Address>003FDCA0</Address>
<Offsets>
<Offset>38C</Offset>
</Offsets>
</CheatEntry>
</CheatEntries>
</CheatTable>
|
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Mon Jan 02, 2017 9:13 am Post subject: |
|
|
You still need to pass the address as "pcsx2-r3878.exe+003FDCA0"
Unless you have a "Player Attributes" record in your table with the address "pcsx2-r3878.exe"
Then you would've needed to pass the address starting with a plus "+003FDCA0"
|
|
Back to top |
|
 |
condamor Newbie cheater
Reputation: 0
Joined: 02 Jan 2017 Posts: 10
|
Posted: Mon Jan 02, 2017 10:17 am Post subject: |
|
|
I tried that and when I do AddCheatTableRecord("Test0", "pcsx2-r3878.exe+003FDCA0", 908, "string", 50) in gives me the below record, which has an offset of 38C. How am I supposed to set the offset for the record and how do I set the lengths for the record types that need them?
Code: | <?xml version="1.0" encoding="utf-8"?>
<CheatTable>
<CheatEntries>
<CheatEntry>
<ID>9237</ID>
<Description>"Test0"</Description>
<LastState Activated="0" RealAddress="00000000"/>
<Color>80000008</Color>
<VariableType>String</VariableType>
<Length>50</Length>
<Unicode>0</Unicode>
<ZeroTerminate>1</ZeroTerminate>
<Address>pcsx2-r3878.exe+003FDCA0</Address>
<Offsets>
<Offset>38C</Offset>
</Offsets>
</CheatEntry>
</CheatEntries>
</CheatTable>
|
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Mon Jan 02, 2017 10:27 am Post subject: |
|
|
Oh, you set the offset as 908 (decimal).
You want the offset 0x908 (hexadecimal).
It correctly gave your string a length of 50.
Perhaps your string is unicode? Code: | NewRecord.String.Unicode = true |
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4702
|
Posted: Mon Jan 02, 2017 10:32 am Post subject: |
|
|
condamor wrote: | How do people usually figure out how to work undocumented things? |
See main.lua for a brief explanation of most classes and functions, and see defines.lua for a list of most constants.
condamor wrote: | I tried that and when I do AddCheatTableRecord("Test0", "pcsx2-r3878.exe+003FDCA0", 908, "string", 50) in gives me the below record, which has an offset of 38C. |
38C is in hexadecimal while 908 is in decimal. They're the same number.
If you want to input the offsets strictly as a number, then as Zanzer said, prefix it with 0x. For more complicated offsets (e.g. symbols), use the OffsetText property.
For the sizes, see main.lua:
Quote: | MemoryRecord Class:
...
Type: ValueType - The variable type of this record. See vtByte to vtCustom
If the type is vtString then the following properties are available:
String.Size: Number of characters in the string
String.Unicode: boolean
If the type is vtBinary then the following properties are available
Binary.Startbit: First bit to start reading from
Binary.Size : Number of bits
If the type is vtByteArray then the following properties are available
Aob.Size : Number of bytes |
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
condamor Newbie cheater
Reputation: 0
Joined: 02 Jan 2017 Posts: 10
|
Posted: Mon Jan 02, 2017 10:32 am Post subject: |
|
|
Thank you, that got me to figure out the offset error was because I wasn't adding "0x" to the _offset variable as I intended and I wasn't passing it in.
How do I set the length for an Array of Bytes record? It'd be nice to know how to do that for a binary type too if it applies, but it's not important because I don't think we've encountered any in our project yet.
EDIT: I still can't double post so..
Oh ha lol thank you both yeah I noticed that when you both did too xD It's not unicode, no. Not this particular string anyways, but I did test the unicode portion a second ago and it was working.
Someone else in this revival project I'm working on asked me if I could find them lua code to do this. I'd like to make sure it's "proper" before I pass it off to him, and to me that means working the binary values correctly as well as the AOB values. I think the rest are right though? I know AOB and String have sizes that need defined, and the rest are a set nber of bytes. Besides binary, I'm not sure how that value type works at all.
I did look in defines for the "vtByte" style code and I did check in Main.lua too. I ctrl+f'd for info in that and only found 1 thing. I could have searched poorly and not found something though.
Edit2: Okay thank you, that probably is all I need. I missed part of that last post. I'll post back in a sec with the new source for people. I did not see that listed in Main.lua so I probably failed at searching through it right.
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Mon Jan 02, 2017 10:57 am Post subject: |
|
|
You should add another parameter _parent and use that to determine where to append the new record. Code: | if _parent ~= nil then
NewRecord.appendToEntry(_parent)
end |
Just for extra functionality, your function should also return the new record.
Also, _offset should be a table that you loop through to add them all.
If someone's using an offset, chances are there's more than one.
As ParkourPenguin pointed out, check if the value is a number or a string and use the correct field. Code: | if _offset ~= nil and type(_offset) == "table" then
NewRecord.OffsetCount = #_offset
local index = 0
for i = #_offset, 1, -1 do
if type(_offset[i]) == "string" then
NewRecord.OffsetText[index] = _offset[i]
else
NewRecord.Offset[index] = _offset[i]
end
index = index + 1
end
end |
|
|
Back to top |
|
 |
mgr.inz.Player I post too much
Reputation: 222
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Mon Jan 02, 2017 11:07 am Post subject: |
|
|
Setting some properties of memory record is little tricky.
For example, Address, it is a string. Do not try assigning numerical types. You must use string. Example:
This code will set address to '400500'.
Code: | CEAddressList = getAddressList()
CEAddressList[0].Address = 0x61C74 |
Yes. Hexadecimal number is silently converted by Lua to 400500 (dec), then converted to string '400500'. And CE internal code interprets this string as hexstring.
So, always use this:
Code: | CEAddressList[0].Address = string.format('%X' , 0x61C74 )
or
CEAddressList[0].Address = string.format('%X' , numericalVariable)
or
CEAddressList[0].Address = '61C74'
|
Saying this just in case you want to use AddCheatTableRecord in a loop.
_________________
|
|
Back to top |
|
 |
condamor Newbie cheater
Reputation: 0
Joined: 02 Jan 2017 Posts: 10
|
Posted: Mon Jan 02, 2017 11:31 am Post subject: |
|
|
Thank you all for the replies!
I personally throw all my addresses into a class that handles all of the writeThing and readThing functions and more.
I'm implementing the _offset change, but can you explain these lines to me?
NewRecord.OffsetCount = #_offset
local index = 0
for i = #_offset, 1, -1 do
is "#_offset" a quick way to get the number of items in the list?
and "for i = #_offset, 1, -1 do"
we're creating and setting i equal to whatever #_offset is, and then looping while i is 1 through -1? I totally don't think that's right? lolol
Now I'm starting to lose touch. How exactly does setting multiple offsets work? Is it going to be like "[pcsx2-r3878.exe+0040239C]+760+ABC+123" or is it going to make multiple records, one for each offset? Like what is the end result going to be. I feel like this is way to call the code once and setup many addresses. But wouldn't it potentially be more beneficial to just loop a call to the function for every offset, since this looks like it would give every offset a generic name?
I was forming the function to be, 1 thing in, 1 thing out.
Can i just replace my if _offset ~= nil statement with yours?
I feel like I should edit it to check if the offset is a table or not, so if only one address is passed in they don't have to pre-parse a single offset into a table just to send it to a function.
I replaced the _parent part at the end with,
Code: | if _parent ~= nil then
NewRecord.appendToEntry(_parent)
else
NewRecord.appendToEntry()
end |
Should that be fine? I misread what the code was doing before and thought it was doing something else.
Here's what in my file now:
Code: | function AddRecordToCheatTable(_description, _address, _offset, _type, _length, _specificData, _parent)
local CEAddressList = getAddressList()
local NewRecord = CEAddressList.createMemoryRecord();
NewRecord.Description = _description
NewRecord.Address = _address
if _offset ~= nil then
NewRecord.OffsetCount = 1
NewRecord.Offset[0] = "0x" .. _offset
end
if _offset ~= nil and type(_offset) == "table" then
NewRecord.OffsetCount = #_offset
local index = 0
for i = #_offset, 1, -1 do
if type(_offset[i]) == "string" then
NewRecord.OffsetText[index] = _offset[i]
else
NewRecord.Offset[index] = _offset[i]
end
index = index + 1
end
end
if _type == "Array of Bytes" then
_type = "Bytes"
elseif _type == "AOB" then
_type = "Bytes"
elseif _type == "array of bytes" then
_type = "Bytes"
elseif _type == "aob" then
_type = "Bytes"
end
if _type == "String" then
NewRecord.Type = vtString
if _length ~= nil then
NewRecord.String.Size = _length
end
if _specificData ~= nil then
NewRecord.String.Unicode = _specificData
end
elseif _type == "Binary" then
NewRecord.Type = vtBinary
NewRecord.Binary.Startbit = _specificData
NewRecord.Binary.Size = _length
elseif _type == "Double" then
NewRecord.Type = vtDouble
elseif _type == "Float" then
NewRecord.Type = vtSingle
elseif _type == "Bytes" then
NewRecord.Type = vtByteArray
NewRecord.Aob.Size = _length
elseif _type == "Byte" then
NewRecord.Type = vtByte
elseif _type == "2 Bytes" then
NewRecord.Type = vtWord
elseif _type == "4 Bytes" then
NewRecord.Type = vtDword
elseif _type == "8 Bytes" then
NewRecord.Type = vtQword
end
if _parent ~= nil then
NewRecord.appendToEntry(_parent)
else
NewRecord.appendToEntry()
end
end |
I know the offset part is there twice, not sure what to do.
I tweaked some names of variables and stuff but the important part is the same.
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Mon Jan 02, 2017 11:39 am Post subject: |
|
|
Yes, #_offset will return the number of items in that table.
for i = #_offset, 1, -1 do
Initialize i to equal the number of items in the table.
While i is greater than or equal to 1, do the loop.
Add -1 to i after each iteration.
If you're familiar with other programming languages:
for (int i = _offset.length; i >= 1; --i) {}
Lua tables start their index at 1, while the CE .Offset array starts at index 0.
The .Offset array is added from top-down visually in the memory record.
This means that index 0 is actually the last offset for the record.
So I flipped the insertion to make it more user friendly.
[pcsx2-r3878.exe+0040239C]+760+ABC+123
So the address above would be added as: Code: | local address = "pcsx2-r3878.exe+0040239C"
local offsets = {0x760, 0xABC, 0x123}
AddCheatTableRecord("Test3", address, offsets, "4 bytes") |
|
|
Back to top |
|
 |
condamor Newbie cheater
Reputation: 0
Joined: 02 Jan 2017 Posts: 10
|
Posted: Mon Jan 02, 2017 11:51 am Post subject: |
|
|
Cg on post 3000! lol
I am familiar with other languages, yes. I never did iterations that way until "recently" and "recently" i've only been using lua which i've been familiarizing myself with lol
Is that really a "do until i = 1" loop though? Or is it literally a "While i is greater than or equal to 1" loop?
Should my offset code be: Code: | if _offset ~= nil
if type(_offset) == "table" then
NewRecord.OffsetCount = #_offset
local index = 0
for i = #_offset, 1, -1 do
if type(_offset[i]) == "string" then
NewRecord.OffsetText[index] = _offset[i]
else
NewRecord.Offset[index] = _offset[i]
end
index = index + 1
end
else
NewRecord.OffsetCount = 1
NewRecord.Offset[0] = "0x" .. _offset
end
end |
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Mon Jan 02, 2017 11:59 am Post subject: |
|
|
Same as a do until, yea. You can code your loops however you like.
for, for each, while, do while, do until... they're all interchangeable
Code: | if _offset ~= nil
if type(_offset) == "table" then
NewRecord.OffsetCount = #_offset
local index = 0
for i = #_offset, 1, -1 do
local offset = _offset[i]
if type(offset) == "string" then
offset = tonumber(offset, 16)
end
NewRecord.Offset[index] = offset
index = index + 1
end
else
if type(_offset) == "string" then
_offset = tonumber(_offset, 16)
end
NewRecord.OffsetCount = 1
NewRecord.Offset[0] = _offset
end
end |
|
|
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
|
|