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 


Multi-address adder
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Affly
Cheater
Reputation: 1

Joined: 29 Sep 2013
Posts: 42

PostPosted: Wed Dec 28, 2016 9:19 am    Post subject: Multi-address adder Reply with quote

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
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Wed Dec 28, 2016 7:29 pm    Post subject: This post has 1 review(s) Reply with quote

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
View user's profile Send private message
Affly
Cheater
Reputation: 1

Joined: 29 Sep 2013
Posts: 42

PostPosted: Thu Dec 29, 2016 7:45 am    Post subject: Reply with quote

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
View user's profile Send private message
condamor
Newbie cheater
Reputation: 0

Joined: 02 Jan 2017
Posts: 10

PostPosted: Mon Jan 02, 2017 4:59 am    Post subject: Reply with quote

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
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Mon Jan 02, 2017 9:13 am    Post subject: Reply with quote

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
View user's profile Send private message
condamor
Newbie cheater
Reputation: 0

Joined: 02 Jan 2017
Posts: 10

PostPosted: Mon Jan 02, 2017 10:17 am    Post subject: Reply with quote

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
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Mon Jan 02, 2017 10:27 am    Post subject: Reply with quote

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
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4702

PostPosted: Mon Jan 02, 2017 10:32 am    Post subject: Reply with quote

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
View user's profile Send private message
condamor
Newbie cheater
Reputation: 0

Joined: 02 Jan 2017
Posts: 10

PostPosted: Mon Jan 02, 2017 10:32 am    Post subject: Reply with quote

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
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Mon Jan 02, 2017 10:57 am    Post subject: Reply with quote

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
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: Mon Jan 02, 2017 11:07 am    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
condamor
Newbie cheater
Reputation: 0

Joined: 02 Jan 2017
Posts: 10

PostPosted: Mon Jan 02, 2017 11:31 am    Post subject: Reply with quote

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
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Mon Jan 02, 2017 11:39 am    Post subject: Reply with quote

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
View user's profile Send private message
condamor
Newbie cheater
Reputation: 0

Joined: 02 Jan 2017
Posts: 10

PostPosted: Mon Jan 02, 2017 11:51 am    Post subject: Reply with quote

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
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Mon Jan 02, 2017 11:59 am    Post subject: Reply with quote

Same as a do until, yea. You can code your loops however you like. Smile
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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine 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