|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
the_elemental_of_creation How do I cheat? Reputation: 0
Joined: 19 Jul 2017 Posts: 5
|
Posted: Thu Jul 27, 2017 11:36 am Post subject: Problem with my code? |
|
|
Recently I have been trying to work on a code that will scan all memory regions from 0x00000000 to 0xffffffff to return a table containing the address of all values that are equal to the variable "value" and have run into a problem where my code causes cheat engine to stop responding, and will never finish. After doing a bunch of investigating into what cheat engine was doing while it was not responding, I found that the code was in fact continuing to execute. If anyone can tell me what the problem with my code is that would be greatly appreciated.
Code: | openProcess([process name])
maxMem=0xffffffff
function scanForVal(value,type,...)
--Ignore the variable "type" as it is not yet implemented properly
if #arg==0 then
local tabl={}
for x=0,maxMem,2 do
if readInteger(x)==value then
table.insert(tabl,x)
print(x)
end
end
return(tabl)
end
local x=1
end
a=scanForVal(22500,1) |
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4289
|
Posted: Thu Jul 27, 2017 12:50 pm Post subject: |
|
|
That code shouldn't run in the first place since arg isn't defined. If you want to use Lua 5.0 vararg features, put this line at the beginning of the function:
Executing that code should take more than an hour to complete. If you want to do it quickly, let CE do it for you. Here's a simple implementation using aobscan:
Code: | function scanForVal(value, type)
local bt
if type == vtDword then
bt = dwordToByteTable(value)
elseif type == vtSingle then
bt = floatToByteTable(value)
--elseif etc...
end
for i,v in ipairs(bt) do
bt[i] = string.format('%02X', bt[i])
end
local t,res = {},AOBScan(table.concat(bt,' '), '-X-C+W', fsmAligned, '4')
for i=0, res.Count-1 do
t[i+1] = res[i] -- results are strings by default
end
res.destroy()
return t
end
local t = scanForVal(1, vtSingle)
for _,v in ipairs(t) do
print(v)
end |
Use memscan class for more advanced stuff (e.g. specifying start/stop region, next scans, value between scans, etc.).
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
the_elemental_of_creation How do I cheat? Reputation: 0
Joined: 19 Jul 2017 Posts: 5
|
Posted: Thu Jul 27, 2017 1:07 pm Post subject: |
|
|
ParkourPenguin wrote: | That code shouldn't run in the first place since arg isn't defined. If you want to use Lua 5.0 vararg features, put this line at the beginning of the function:
|
You see that "..." in the function that I had defined? That is the table arg, defined by lua for the function. Any additional arguments in the function (this function is designed to take an "infinite" (only limited by lua's capabilities) number of arguments) are put into the table arg. If you were to do, for example, Code: | function test(...)
for x=1,#arg do
print(arg[1])
end
end
test("hello",35,"see")
|
the output would be
Also, if arg was not defined, would not work.
I will try your code example when I have a chance, but I need to know, is the output for scanForVal() a table in your example?
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4289
|
Posted: Thu Jul 27, 2017 1:23 pm Post subject: |
|
|
You're using an old version of CE then. Under the current version of CE, this code:
Code: | local function f(...)
print(type(arg))
print(...)
end
f('str') | has this output:
Read this section of the Lua 5.3 reference manual for more information. Specifically:
Quote: | A vararg function does not adjust its argument list; instead, it collects all extra arguments and supplies them to the function through a vararg expression, which is also written as three dots. The value of this expression is a list of all actual extra arguments, similar to a function with multiple results. |
the_elemental_of_creation wrote: | ...is the output for scanForVal() a table in your example? |
In my example, scanForVal returns a table of strings properly formatted as a Lua array (i.e. contiguous integer indices starting at 1).
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
the_elemental_of_creation How do I cheat? Reputation: 0
Joined: 19 Jul 2017 Posts: 5
|
Posted: Thu Jul 27, 2017 1:38 pm Post subject: |
|
|
ParkourPenguin wrote: | You're using an old version of CE then. Under the current version of CE, this code:
Code: | local function f(...)
print(type(arg))
print(...)
end
f('str') | has this output:
Read this section of the Lua 5.3 reference manual for more information. Specifically:
Quote: | A vararg function does not adjust its argument list; instead, it collects all extra arguments and supplies them to the function through a vararg expression, which is also written as three dots. The value of this expression is a list of all actual extra arguments, similar to a function with multiple results. |
the_elemental_of_creation wrote: | ...is the output for scanForVal() a table in your example? |
In my example, scanForVal returns a table of strings properly formatted as a Lua array (i.e. contiguous integer indices starting at 1). |
Okay, so my new code is Code: | openProcess([process name])
maxMem=0xffffffff
function scanForVal(value,type,...)
local arg={...}
--Ignore the variable "type" as it is not yet implemented properly
if #arg==0 then
local tabl={}
for x=0,maxMem,2 do
if readInteger(x)==value then
table.insert(tabl,x)
print(x)
end
end
return(tabl)
end
local x=1
end
a=scanForVal(22500,1) |
Why would this code never finish executing even after more than 5 hours?
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4289
|
Posted: Thu Jul 27, 2017 1:57 pm Post subject: |
|
|
Because it takes a long time to scan through over 2 billion values with a single thread in Lua. Try testing it at a lower number and see how long it takes. For example:
Code: | local maxMem = 0x100000
function scanForVal(value, type)
local tBeg = getTickCount()
local tabl = {}
for x=0, maxMem, 2 do
assert(getTickCount() - tBeg < 60000, 'timeout') -- timeout after 1 minute
if readInteger(x) == value then
table.insert(tabl,x)
end
end
print('Milliseconds elapsed:', getTickCount() - tBeg)
return(tabl)
end
scanForVal(22500,1) |
Scanning through the first 256 pages of memory of the CE Tutorial takes a little over a second for me.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
panraven Grandmaster Cheater Reputation: 55
Joined: 01 Oct 2008 Posts: 942
|
Posted: Thu Jul 27, 2017 2:47 pm Post subject: |
|
|
Reading remote memory has a much high overhead than local memory
because the inter-process mechanism eg. through readProcessMemory API.
so it is better to have a buffer to batch read local memory of remote process,
with larger size the batch, then to have a lesser number of inter-process transfer eg.
to read A*B unit of remote memory, it is better to do
A times of remote transfer, by reading B unit buffer of local memory each than
A*B times of remote transfer of 1 unit of local memory read each.
Lua function readBytes can use as such buffer, but care should be make that the buffer size should match the memory region granularity (1K or 4K ?) , can there may be instance of reading a unreadable region etc.
ParkourPenguin's AOBScan solution should be better than buffer approach since less care of the detail.
_________________
- Retarded. |
|
Back to top |
|
|
the_elemental_of_creation How do I cheat? Reputation: 0
Joined: 19 Jul 2017 Posts: 5
|
Posted: Thu Jul 27, 2017 4:04 pm Post subject: |
|
|
ParkourPenguin wrote: | That code shouldn't run in the first place since arg isn't defined. If you want to use Lua 5.0 vararg features, put this line at the beginning of the function:
Executing that code should take more than an hour to complete. If you want to do it quickly, let CE do it for you. Here's a simple implementation using aobscan:
Code: | function scanForVal(value, type)
local bt
if type == vtDword then
bt = dwordToByteTable(value)
elseif type == vtSingle then
bt = floatToByteTable(value)
--elseif etc...
end
for i,v in ipairs(bt) do
bt[i] = string.format('%02X', bt[i])
end
local t,res = {},AOBScan(table.concat(bt,' '), '-X-C+W', fsmAligned, '4')
for i=0, res.Count-1 do
t[i+1] = res[i] -- results are strings by default
end
res.destroy()
return t
end
local t = scanForVal(1, vtSingle)
for _,v in ipairs(t) do
print(v)
end |
Use memscan class for more advanced stuff (e.g. specifying start/stop region, next scans, value between scans, etc.). |
So, after a few tweaks to change the way it works with the values the code works perfectly for my needs. Thanks for your help. This is the new code:
Code: | openProcess([process name])
function DEC_HEX(IN)
local B,K,OUT,I,D=16,"0123456789ABCDEF","",0
while IN>0 do
I=I+1
IN,D=math.floor(IN/B),math.mod(IN,B)+1
OUT=string.sub(K,D,D)..OUT
end
return OUT
end
function scanForVal(value,type,...)
local bt
local arg={...}
if type==vtDword then
bt=dwordToByteTable(value)
elseif type==vtSingle then
bt=floatToByteTable(value)
--elseif etc...
end
for i,v in ipairs(bt) do
bt[i] = string.format('%02X', bt[i])
end
local t,res={},AOBScan(table.concat(bt,' '),'-X-C+W',fsmAligned,'4')
for i=0,res.Count-1 do
t[i+1] = res[i] -- results are strings by default
end
res.destroy()
local g=0
--[[
Hello there. Let me give you a quick explanation on how to properly input arguments into this function. The first argument is "value"
This argument is the first value that we are searching for. The next argument is "type". This currently only works with vtDword
After that is the magical "...". This is symbolic for the rest of the arguments. The first line
checks to see if there are any more arguments. If that is the case, it executes the following lines which will return a table of every occurance of "value"
Otherwise, it will do much more complicated work starting with setting that variable x to 1
Each odd argument in the ... is a second value to look for, in relation to the first value. I'll explain what that means in a moment. Each even argument is the hexadecimal offset for the argument before it.
Let me explain what is happening. The function will first search for the first value. Once it finds it, it will read the value of each number that is a certain distance away from it. So if you have the first value at 0x00000001, and argument 1 and argument 2 are 17 and 345 respectively, the function will then check to see if the value at 0x00000001+345(0x00000346) is equal to the value of argument1 (17). If it is, then it will do the same for the next to arguments (should they exist).
If they are not the same, however, then it will search for the next occurence of "value" and repeat those checks until it is true for all arguments.
]]
if #arg==0 then
return t
else
for x=1,#t do
local address=tonumber("0x"..t[x])
for z=1,#arg,2 do
if readInteger(address+arg[z])~=arg[z+1] then
g=0
break
else
g=g+1
end
end
if g==(#arg/2) then
local addTable={}
addTable[1]=DEC_HEX(address)
for z=1,#arg,2 do
table.insert(addTable,DEC_HEX(address+arg[z]))
end
return(addTable)
end
end
end
end
t=scanForVal(220055555,vtDword,0x00000008,243,0x00000020,6) |
|
|
Back to top |
|
|
dl748 Advanced Cheater Reputation: 0
Joined: 05 Mar 2016 Posts: 75
|
Posted: Sat Jul 29, 2017 5:35 pm Post subject: |
|
|
i use a simpler script for converting to hex
Code: | local function hex(a, c)
if a == nil then
return "(nil)"
end
local fmt = "%X"
if type(c) == "number" then
fmt = "%0"..c.."X"
end
return string.format(fmt, a)
end
|
has the ability to specify a size as well (for padding) if you don't want that
Code: | local function hex(a, c)
if a == nil then
return "(nil)"
end
return string.format("%X", a)
end |
|
|
Back to top |
|
|
the_elemental_of_creation How do I cheat? Reputation: 0
Joined: 19 Jul 2017 Posts: 5
|
Posted: Wed Aug 02, 2017 8:04 pm Post subject: |
|
|
dl748 wrote: | i use a simpler script for converting to hex
Code: | local function hex(a, c)
if a == nil then
return "(nil)"
end
local fmt = "%X"
if type(c) == "number" then
fmt = "%0"..c.."X"
end
return string.format(fmt, a)
end
|
has the ability to specify a size as well (for padding) if you don't want that
Code: | local function hex(a, c)
if a == nil then
return "(nil)"
end
return string.format("%X", a)
end |
|
Why is c there in the second code?
|
|
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
|
|