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 


Write String (larger or smaller string)

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
faizangmc
Expert Cheater
Reputation: 0

Joined: 12 Nov 2013
Posts: 167

PostPosted: Fri Sep 26, 2014 5:05 am    Post subject: Write String (larger or smaller string) Reply with quote

Hello,
I have made an editor for a simulation game for changing the player names.

I found the right pointer for it.

The format of the name is as follows :

First Name
Initials
Last Name

Separate pointers for all three.

The problem is if i use writeString function in lua with an edit box placed. If i write a Larger string, It removes the last name and shows only the equal no of strings in first name as the previous first name.

Also, if i use .CT table do so, still the same results.

What can I use in writeString(adress,value)
so that even if i write larger or smaller string, it does so properly

Thanks.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

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

PostPosted: Fri Sep 26, 2014 5:53 am    Post subject: Reply with quote

Calculate the length of the string and then at the address+strlen write a byte with the value 0
_________________
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: 218

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

PostPosted: Fri Sep 26, 2014 6:28 am    Post subject: Reply with quote

Code:
myString = 'whatever'

//Ansi
writeString(address, myString)
writeBytes(address+#myString, 0)


//Unicode
writeString(address, myString, true)
writeBytes(address+#myString*2, 0, 0)

_________________
Back to top
View user's profile Send private message MSN Messenger
panraven
Grandmaster Cheater
Reputation: 54

Joined: 01 Oct 2008
Posts: 941

PostPosted: Fri Sep 26, 2014 9:09 am    Post subject: Reply with quote

updated to more fit op requirement
(3rd update, fix szfill)

Better try this in a notepad 1st.

-- new --
Code:
local debug_print = false
local schar,sbyte,slen,ssub = string.char,string.byte,string.len,string.sub
local tinsert,tconcat,tremove = table.insert,table.concat,table.remove
function t2aob(t) local s = {} for i=1,#t do tinsert(s,string.format('%02X',t[i])) end return tconcat(s,' ') end
function s2b(s,wide) -- convert a lua string to byte with/wo wide encoding
  local t={}
  for i=1,slen(s) do tinsert(t,sbyte(ssub(s,i,i))) ; if wide then tinsert(t,0) end end
  return t
end
function sz(b,wide) -- terminate a byte array as czstring
  tinsert(b,0)
  if wide then tinsert(b,0) end
end
-- b is the byte array of string to test, string len must > 2 (wide) or 3 (ascii)
function iswide(b) return #b>2 and b[0] ~= 0 and b[1] == 0 and b[2] ~= 0 end
function seeksz(b,wide)
  local szpos,step = bShl(1,47) ,wide and 2 or 1
  for i=1,#b,step do
    if b[i] == 0 then
      szpos = i - step
      break
    end
  end
  return szpos
end
function string.patchAt(self, at, forceWide,szfill, knowntdst) -- forceWide = nil to auto detect
  local mcnt, addrs = 0, type(at) == 'table' and at or {at}
  if type(at) == 'userdata' then -- class Strings or Stringlist
    addrs = {} ; for i=1,at.getCount() do tinsert(addrs,at[i-1]) end
  end
  if debug_print then for i=1,#addrs do print(i,addrs[i]) end end
  if #addrs > 0 then
    local wide = type(forceWide) == 'nil' and iswide(readBytes(addrs[1],3)) or forceWide or false
    local tdst = knowntdst or s2b(self,wide)
    for i=1,#addrs do
      local addr = addrs[i]
      local target = table.pack(readBytes(addr,#tdst))
      local szpos = seeksz(target,wide)
      local modln = math.min(#tdst,szpos)
      while #target > modln do tremove(target) end
      for i=1,modln do target[i] = tdst[i] end
      if szfill then sz(target) end
      fullAccess(addr,#target)
      if pcall(writeBytes,addr,target) then mcnt = mcnt + 1 end
    end
  end
  return mcnt
end
local strPatchAt = string.patchAt

function patchAoB(a,b,...) -- not quite fit op requirement
  local scan,mcnt = AOBScan(t2aob(a),...),0
  if scan then
    for i=0,scan.getCount()-1 do -- don't know if pcall work for writeBytes
      local addr = scan[i]
--      print(addr) --  remove for non debug
      fullAccess(addr,#b) -- not sure if pcall work for writebytes on error
      if pcall(writeBytes,addr,b) then mcnt = mcnt + 1 end
    end
    object_destroy(scan)
  end
  return mcnt
end

function patchStrEx(src,dst,wide,szfill,...)
  local dstlen = math.min(slen(src),slen(dst))
  local dst = ssub(dst,1,dstlen)
  local tsrc,tdst = s2b(src,wide),s2b(dst,wide)

  local mcnt, scan= 0, AOBScan(t2aob(tsrc))
  if scan then
    mcnt = dst:patchAt(scan,wide,szfill,tdst)
    object_destroy(scan)
  end
  return mcnt
end
function patchStr(a,b,wide,szfill,...)
  local mcnt,mode,szfill = 0,type(wide) == 'nil' and 3 or wide == true and 2 or 1, szfill or false
  if bAnd(mode,1) then mcnt = mcnt + patchStrEx(a,b,false,szfill,...) end
  if bAnd(mode,2) then mcnt = mcnt + patchStrEx(a,b,true,szfill,...) end
  return mcnt
end

-- for test
debug_print = false
openProcess("notepad.exe")
-- type this at notepad : ---a12345----a12345---a12345----
local a,b = "a12345","b54321xxx"
local c,d = "b54321","a12345yyy"
print(string.format("%04X",getOpenedProcessID()))
local e = patchStr(a,b,nil,false,"-X+W-C") -- nil to try patch both ascii and wide
if e > 0 then
  print("a>b-",e)
else
  print("b>a-",patchStr(c,d,nil,false,"-X+W-C"))
end

-- string.patchAt can work alone, should more fit the op's requirement
-- but the addres table and/or patch byte table has to be prepared before hand.






-- old --
Code:
local schar,sbyte,slen,ssub = string.char,string.byte,string.len,string.sub
local tinsert,tconcat,tremove = table.insert,table.concat,table.remove
function t2aob(t) local s = {} for i=1,#t do tinsert(s,string.format('%02X',t[i])) end return tconcat(s,' ') end
function s2b(s,wide) -- convert a lua string to byte with/wo wide encoding
  local t={}
  for i=1,slen(s) do tinsert(t,sbyte(ssub(s,i,i))) ; if wide then tinsert(t,0) end end
  return t
end
function sz(b,wide) -- terminate a byte array as czstring
  tinsert(b,0)
  if wide then tinsert(b,0) end
end
function patchAoB(a,b,...)
  local scan,mcnt = AOBScan(t2aob(a),...),0
  if scan then
    for i=0,scan.getCount()-1 do --
      local addr = scan[i]
      print(addr) --  remove for non debug ***********
      fullAccess(addr,#b) -- not sure if pcall work for writebytes on error
      if pcall(writeBytes,addr,b) then mcnt = mcnt + 1 end
    end
    object_destroy(scan)
  end
  return mcnt
end
function patchStrEx(src,dst,wide,szfill,...)
  local dstlen = math.min(slen(src),slen(dst))
  local dst = ssub(dst,1,dstlen)
  local tsrc,tdst = s2b(src,wide),s2b(dst,wide)
  if szfill then sz(tdst,wide) end-- add string terminator
  return patchAoB(tsrc,tdst,...)
end
function patchStr(a,b,wide,szfill,...)
  local mcnt,mode,szfill = 0,type(wide) == 'nil' and 3 or wide == false and 1 or 2, szfill or false
  if bAnd(mode,1) then mcnt = mcnt + patchStrEx(a,b,false,szfill,...) end
  if bAnd(mode,2) then mcnt = mcnt + patchStrEx(a,b,true,szfill,...) end
  return mcnt
end

-- for test
openProcess("notepad.exe")
local a,b = "a12345","b54321xxx"
print(string.format("%04X",getOpenedProcessID()))
print(patchStr(a,b,nil,false,"-X+W-C")) -- nil to try patch both ascii and wide
--print(patchStr(b,a,nil,false,"-X+W-C"))



Last edited by panraven on Fri Sep 26, 2014 7:25 pm; edited 4 times in total
Back to top
View user's profile Send private message
faizangmc
Expert Cheater
Reputation: 0

Joined: 12 Nov 2013
Posts: 167

PostPosted: Fri Sep 26, 2014 4:21 pm    Post subject: Reply with quote

thanks of all you. will try these when I reach home Smile (now at work)
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 218

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

PostPosted: Fri Sep 26, 2014 9:06 pm    Post subject: Reply with quote

For larger strings, it is possible and, of course, more complicated.

The choice of method depends on many factors. Is it older game (unmanaged code, written in C, C++, Pascal) or newer game (managed code, written in J#, C#, C++, Java, Lua; executed under the management of a .NET/Mono/JVM/et cetera).

You have to allocate new memory for string object, find all references to old string and then edit/adjust them for new string.

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