|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
fakuivan Newbie cheater Reputation: 0
Joined: 27 Dec 2018 Posts: 17
|
Posted: Thu Dec 27, 2018 6:49 pm Post subject: Fetch static address from opcode using aob signature |
|
|
How can I get a static address using the aob signature for an opcode that has it? The static address changes when the game gets updated.
This is what the "AOB Injection" template for that opcode looks like
Code: | { Game : Dishonored2.exe
Version:
Date : 2018-12-27
Author : fakui
This script does blah blah blah
}
[ENABLE]
aobscanmodule(INJECT,Dishonored2.exe,F3 0F 10 05 38 54 81 03) // should be unique
alloc(newmem,$1000,"Dishonored2.exe"+3E78CC)
label(code)
label(return)
newmem:
code:
movss xmm0,[Dishonored2.exe+3BFCD0C]
jmp return
INJECT:
jmp newmem
nop
nop
nop
return:
registersymbol(INJECT)
[DISABLE]
INJECT:
db F3 0F 10 05 38 54 81 03
unregistersymbol(INJECT)
dealloc(newmem)
{
// ORIGINAL CODE - INJECTION POINT: "Dishonored2.exe"+3E78CC
"Dishonored2.exe"+3E78A0: EB 04 - jmp Dishonored2.exe+3E78A6
"Dishonored2.exe"+3E78A2: 4C 89 49 10 - mov [rcx+10],r9
"Dishonored2.exe"+3E78A6: 48 8D 05 63 84 1B 03 - lea rax,[Dishonored2.exe+359FD10]
"Dishonored2.exe"+3E78AD: 48 89 41 30 - mov [rcx+30],rax
"Dishonored2.exe"+3E78B1: 48 8B 05 28 83 1B 03 - mov rax,[Dishonored2.exe+359FBE0]
"Dishonored2.exe"+3E78B8: 48 89 01 - mov [rcx],rax
"Dishonored2.exe"+3E78BB: 48 8B 45 B8 - mov rax,[rbp-48]
"Dishonored2.exe"+3E78BF: 48 85 C0 - test rax,rax
"Dishonored2.exe"+3E78C2: 74 5A - je Dishonored2.exe+3E791E
"Dishonored2.exe"+3E78C4: F3 0F 10 98 6C 3A 00 00 - movss xmm3,[rax+00003A6C]
// ---------- INJECTING HERE ----------
"Dishonored2.exe"+3E78CC: F3 0F 10 05 38 54 81 03 - movss xmm0,[Dishonored2.exe+3BFCD0C] // <--- This is the static address I need
// ---------- DONE INJECTING ----------
"Dishonored2.exe"+3E78D4: F3 0F 59 05 7C 9B C8 01 - mulss xmm0,[Dishonored2.exe+2071458]
"Dishonored2.exe"+3E78DC: F3 0F 10 2D 70 9D C8 01 - movss xmm5,[Dishonored2.exe+2071654]
"Dishonored2.exe"+3E78E4: F3 0F 5E D8 - divss xmm3,xmm0
"Dishonored2.exe"+3E78E8: 0F 28 E3 - movaps xmm4,xmm3
"Dishonored2.exe"+3E78EB: F3 0F 5D E5 - minss xmm4,xmm5
"Dishonored2.exe"+3E78EF: F3 0F 59 25 55 7F 1B 03 - mulss xmm4,[Dishonored2.exe+359F84C]
"Dishonored2.exe"+3E78F7: 0F 28 C4 - movaps xmm0,xmm4
"Dishonored2.exe"+3E78FA: F3 0F 5C C5 - subss xmm0,xmm5
"Dishonored2.exe"+3E78FE: 0F 28 C8 - movaps xmm1,xmm0
"Dishonored2.exe"+3E7901: 66 0F 6F 15 07 B1 C8 01 - movdqa xmm2,[Dishonored2.exe+2072A10]
} |
|
|
Back to top |
|
|
OldCheatEngineUser Whateven rank Reputation: 20
Joined: 01 Feb 2016 Posts: 1587
|
Posted: Fri Dec 28, 2018 3:40 am Post subject: |
|
|
what do you mean?
if you want the address to be in address-list:
Dishonored2.exe+3BFCD0C <---copy / paste in "add address manually"
if you meant anorher thing, please tell.
_________________
About Me;
I Use CE Since Version 1.X, And Still Learning How To Use It Well!
Jul 26, 2020
STN wrote: | i am a sweetheart. |
|
|
Back to top |
|
|
fakuivan Newbie cheater Reputation: 0
Joined: 27 Dec 2018 Posts: 17
|
Posted: Fri Dec 28, 2018 3:12 pm Post subject: |
|
|
I could just copy the static address, but it changes on game updates. Is there any way I can use the offset to that opcode to fetch it from there? Instead of copying manually.
Essentially I'm looking for a procedure to read the opcode at "Dishonored2.exe"+3E78CC and from there get the static address used by that opcode (Dishonored2.exe+3BFCD0C)
|
|
Back to top |
|
|
OldCheatEngineUser Whateven rank Reputation: 20
Joined: 01 Feb 2016 Posts: 1587
|
Posted: Fri Dec 28, 2018 4:57 pm Post subject: |
|
|
fakuivan wrote: | Is there any way I can use the offset to that opcode to fetch it from there? Instead of copying manually. |
maybe you can use ReadMem in your script, read 4 byte after inject symbol. (i mean after F3 0F 10 05)
you can use wildcards * or ? or both, example:
Code: | aobscanmodule(INJECT,Dishonored2.exe,F3 0F 10 05 ** ?? ?? **) |
however this is not unique and must be extended, you can take bytes from following instruction. (instruction that comes next) F3 0F 59 05
Code: | F3 0F 10 05 ** ?? ?? ** F3 0F 59 05 |
you can take bytes from preceding instruction (previous instruction) 00 00, but you must change some contents of your script:
Code: | { Game : Dishonored2.exe
Version:
Date : 2018-12-27
Author : fakui
This script does blah blah blah
}
[ENABLE]
aobscanmodule(INJECT,Dishonored2.exe,00 00 F3 0F 10 05 ** ?? ?? ** F3 0F 59 05) // should be unique
alloc(newmem,$1000,"Dishonored2.exe"+3E78CC)
label(code)
label(return)
newmem:
code:
movss xmm0,[Dishonored2.exe+3BFCD0C] // you must fix it if it changed
jmp return
INJECT+02:
jmp newmem
nop
nop
nop
return:
registersymbol(INJECT)
[DISABLE]
INJECT+02:
db F3 0F 10 05 38 54 81 03 // you must fix it if it changed
unregistersymbol(INJECT)
dealloc(newmem)
{
// ORIGINAL CODE - INJECTION POINT: "Dishonored2.exe"+3E78CC
"Dishonored2.exe"+3E78A0: EB 04 - jmp Dishonored2.exe+3E78A6
"Dishonored2.exe"+3E78A2: 4C 89 49 10 - mov [rcx+10],r9
"Dishonored2.exe"+3E78A6: 48 8D 05 63 84 1B 03 - lea rax,[Dishonored2.exe+359FD10]
"Dishonored2.exe"+3E78AD: 48 89 41 30 - mov [rcx+30],rax
"Dishonored2.exe"+3E78B1: 48 8B 05 28 83 1B 03 - mov rax,[Dishonored2.exe+359FBE0]
"Dishonored2.exe"+3E78B8: 48 89 01 - mov [rcx],rax
"Dishonored2.exe"+3E78BB: 48 8B 45 B8 - mov rax,[rbp-48]
"Dishonored2.exe"+3E78BF: 48 85 C0 - test rax,rax
"Dishonored2.exe"+3E78C2: 74 5A - je Dishonored2.exe+3E791E
"Dishonored2.exe"+3E78C4: F3 0F 10 98 6C 3A 00 00 - movss xmm3,[rax+00003A6C]
// ---------- INJECTING HERE ----------
"Dishonored2.exe"+3E78CC: F3 0F 10 05 38 54 81 03 - movss xmm0,[Dishonored2.exe+3BFCD0C] // <--- This is the static address I need
// ---------- DONE INJECTING ----------
"Dishonored2.exe"+3E78D4: F3 0F 59 05 7C 9B C8 01 - mulss xmm0,[Dishonored2.exe+2071458]
"Dishonored2.exe"+3E78DC: F3 0F 10 2D 70 9D C8 01 - movss xmm5,[Dishonored2.exe+2071654]
"Dishonored2.exe"+3E78E4: F3 0F 5E D8 - divss xmm3,xmm0
"Dishonored2.exe"+3E78E8: 0F 28 E3 - movaps xmm4,xmm3
"Dishonored2.exe"+3E78EB: F3 0F 5D E5 - minss xmm4,xmm5
"Dishonored2.exe"+3E78EF: F3 0F 59 25 55 7F 1B 03 - mulss xmm4,[Dishonored2.exe+359F84C]
"Dishonored2.exe"+3E78F7: 0F 28 C4 - movaps xmm0,xmm4
"Dishonored2.exe"+3E78FA: F3 0F 5C C5 - subss xmm0,xmm5
"Dishonored2.exe"+3E78FE: 0F 28 C8 - movaps xmm1,xmm0
"Dishonored2.exe"+3E7901: 66 0F 6F 15 07 B1 C8 01 - movdqa xmm2,[Dishonored2.exe+2072A10]
} |
when CE found the given pattern, it will assign the symbol INJECT to that address and then it get replaced with a jump:
Code: | INJECT:
jmp newmem
nop
nop
nop |
but since we added two-bytes in-front of our instruction bytes, then we must tell CE to place the jump two-byte after the current address of INJECT
Code: | INJECT+02:
jmp newmem
nop
nop
nop |
if the scan failed, then replace the bytes with these:
Code: | 00 00 F3 0F 10 ?D ** ?? ?? ** F3 0F 59 ?D // if failed again use ?5 |
yeah i know, you may ask why ?D while original byte 05
this have to do with instruction encoding, the Reg field of ModR/M Byte.
_________________
About Me;
I Use CE Since Version 1.X, And Still Learning How To Use It Well!
Jul 26, 2020
STN wrote: | i am a sweetheart. |
|
|
Back to top |
|
|
fakuivan Newbie cheater Reputation: 0
Joined: 27 Dec 2018 Posts: 17
|
Posted: Fri Dec 28, 2018 6:07 pm Post subject: |
|
|
I appreciate your time but I don't think you understand the question. I don't want to inject anything, I'm merely using the aobscan directive to find the opcode that has the offset for the static address. Again I need some procedure that can read the opcode and extract the offset, just that.
|
|
Back to top |
|
|
OldCheatEngineUser Whateven rank Reputation: 20
Joined: 01 Feb 2016 Posts: 1587
|
Posted: Fri Dec 28, 2018 6:10 pm Post subject: |
|
|
readmem, but must be injected. (told you that)
_________________
About Me;
I Use CE Since Version 1.X, And Still Learning How To Use It Well!
Jul 26, 2020
STN wrote: | i am a sweetheart. |
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4291
|
Posted: Fri Dec 28, 2018 7:39 pm Post subject: |
|
|
Does that offset from the beginning of the module actually change, or are you using the absolute address instead of module+offset?
That instruction uses RIP-relative addressing. The displacement operand 0x3815438 is added to the next instruction's address Dishonored2.exe+3E78D4 which results in the effective address Dishonored2.exe+3BFCD0C.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25288 Location: The netherlands
|
Posted: Fri Dec 28, 2018 11:45 pm Post subject: |
|
|
"reassemble(address)" might help
_________________
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 |
|
|
fakuivan Newbie cheater Reputation: 0
Joined: 27 Dec 2018 Posts: 17
|
Posted: Fri Dec 28, 2018 11:50 pm Post subject: |
|
|
A proposed solution by Raijinili at irc://irc.p2p-network.net/cef ("Sorry, but you can't post url's yet", yes I can)
Code: |
[21:11:03] <fakuivan> How can I programmatically extract a static address from the address to an opcode that accesses it?
[21:13:09] <Raijinili> Is it always the same opcode?
[21:13:46] <Raijinili> For example, if it's always of the form `add eax,[ADDR]`, you can read from an offset.
[21:14:37] <fakuivan> I think
[21:14:38] <Raijinili> You can also try https://wiki.cheatengine.org/index.php?title=Lua:disassemble with https://wiki.cheatengine.org/index.php?title=Lua:splitDisassembledString
[21:14:47] <Raijinili> and then parse the string.
[21:14:58] <fakuivan> Interesting
[21:15:12] <fakuivan> Is my question clear tho?
[21:15:44] <Raijinili> It is unclear whether you want to solve the general problem or a specific subproblem.
[21:15:53] <fakuivan> The thing is the static address changes in between updates
[21:16:16] <fakuivan> If I don't update the game, the address works fine
[21:17:09] <fakuivan> But when I update it, it changes the offset, I'm trying to use the opcode that read it
[21:17:34] <fakuivan> That reads it*
[21:17:40] <Raijinili> Then you're reading it from a specific instruction.
[21:17:51] <fakuivan> So when the address changes the signature to that opcode can be used to find it
[21:18:31] <Raijinili> The opcode is the bits that determine what operation to perform.
[21:19:01] <fakuivan> The key here is that I need to analyze the opcode and extract the static address from it
[21:19:22] <fakuivan> Yes
[21:20:22] <Raijinili> For `add eax,edx`, the operation is "add", and the operation is 01 or something.
[21:20:35] <Raijinili> opcode is 01 or something*
[21:22:12] <Raijinili> Is the instruction's address static?
[21:22:28] <fakuivan> The opcode will stay the same once I make the signature
[21:25:57] <fakuivan> https://forum.cheatengine.org/viewtopic.php?p=5744993#5744993
[21:25:57] <fakuivan> I went into more detail there
[21:26:12] <Raijinili> Take this example: "Dishonored2.exe"+3E78CC: F3 0F 10 05 38 54 81 03 - movss xmm0,[Dishonored2.exe+3BFCD0C]
[21:26:27] <Raijinili> You see those bytes? F3 0F 10 05 38 54 81 03
[21:26:35] <Raijinili> The last four bytes determine the offset.
[21:27:07] <Raijinili> However, it seems to be relative.
[21:31:44] <Raijinili> Okay, it seems to be relative to the following address.
[21:35:12] <Raijinili> If your instruction is always of the form `movss xmm0,[ADDR]`, that instruction is always eight bytes long. Let's say the instruction's address is X. Then read a dword from X+4, and add X+8 to it.
[21:35:37] <Raijinili> Or use the disassemble+parse method.
[21:37:02] <Raijinili> I think OldCheatEngineUser gave the offset+read trick.
[21:40:25] <Raijinili> Instead of guessing, you can use this to get the current instruction's size: https://wiki.cheatengine.org/index.php?title=Lua:getInstructionSize
[21:40:31] <fakuivan> I think I'll use the disassemble+parse method as it sounds more stable
[21:40:57] <fakuivan> Wait
[21:41:07] <fakuivan> Do I have to parse the asm string?
[21:41:28] <Raijinili> https://wiki.cheatengine.org/index.php?title=Lua:splitDisassembledString
[21:42:30] <fakuivan> Neat!
[21:42:40] <fakuivan> That's just what I need
[21:43:10] <Raijinili> I linked it before.
[21:43:31] <Raijinili> Here's the reference list: https://wiki.cheatengine.org/index.php?title=Lua#Assembly
[21:44:32] <fakuivan> Ik, I'm on cellular so I avoid opening links unless necessary :p
[21:44:47] <fakuivan> Thanks a lot
[21:44:58] <fakuivan> I was on a dead end with this one
[21:45:35] <Raijinili> I had a similar question, but it didn't solidify enough for me to search for it.
|
|
|
Back to top |
|
|
panraven Grandmaster Cheater Reputation: 55
Joined: 01 Oct 2008 Posts: 942
|
Posted: Sat Dec 29, 2018 2:31 am Post subject: |
|
|
Code: |
{$lua}
function RIP(n,ofs)n = (tonumber(n,16)or n)+(ofs or 0) return n+readInteger(n,true)+4 end
{$asm}
aobscan(relative, F3 0F 10 05 ?? ?? ?? ?? ... )
// relative address start at relative+4
unregisterSymbol(absolute)
label(absolute)
registerSymbol(absolute)
//// ugly
$((function(n)return n + readInteger(n,true)+4 end)(tonumber('relative',16)+4)):
absolute:
//// neat
//$RIP('relative',4)): // get RIP address at (aa format)relative+4
//absolute:
|
_________________
- Retarded. |
|
Back to top |
|
|
fakuivan Newbie cheater Reputation: 0
Joined: 27 Dec 2018 Posts: 17
|
Posted: Tue Jan 01, 2019 5:08 pm Post subject: |
|
|
I made a function in lua to extract an RIP-relative address from an arbitrary instruction at an arbitrary offset and size:
Code: |
-- Reads a RIP-relative address from an instruction
-- All parameters should be integers
function extractRIPRelativeAddress(address, offset, offset_size)
local instruction_size = getInstructionSize(address)
readOffset = ({
[1] = function(address_) return readBytes(address_, 1, false) end,
[2] = readSmallInteger,
[4] = readInteger,
[8] = readQword
})[offset_size]
if readOffset == nil then return nil end
offset = (tonumber(offset) or 0)
-- Simple check to see if the offset and size move outside the instruction
if instruction_size == nil or instruction_size < offset + offset_size then
return nil
end
local stored_address_ptr = address + (offset or 0)
return address + instruction_size + readOffset(stored_address_ptr)
end
-- Extracts the address from the je instruction
-- Dishonored2.exe+3E7893 - 74 0D - je Dishonored2.exe+3E78A2
print(
getNameFromAddress(
extractRIPRelativeAddress(getAddress('Dishonored2.exe+3E7893'),01,01)
)
)
-- Dishonored2.exe+3E78CC - F3 0F10 05 38548103 - movss xmm0,[Dishonored2.exe+3BFCD0C]
print(
getNameFromAddress(
extractRIPRelativeAddress(getAddress('"Dishonored2.exe"+3E78CC'),04,04)
)
)
|
I can later make a wrapper to expose the function to the auto assembler using ``registerAutoAssemblerCommand``. I could not get this working using the ``$()`` syntax, as the script would not pass the syntax check.
|
|
Back to top |
|
|
fakuivan Newbie cheater Reputation: 0
Joined: 27 Dec 2018 Posts: 17
|
Posted: Thu Jan 10, 2019 9:43 pm Post subject: |
|
|
This is the final script in case anyone needs something similar in the future (link in image description).
Description: |
https://gist.github.com/fakuivan/5b4c6bd334c55407952f3557dad2362c |
|
Filesize: |
11.3 KB |
Viewed: |
4536 Time(s) |
|
|
|
Back to top |
|
|
fakuivan Newbie cheater Reputation: 0
Joined: 27 Dec 2018 Posts: 17
|
Posted: Thu Jan 24, 2019 12:43 am Post subject: |
|
|
The script I posted is having problems with negative offsets. How can I convert the offset to signed once I read it?
|
|
Back to top |
|
|
TheyCallMeTim13 Wiki Contributor Reputation: 50
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Thu Jan 24, 2019 3:32 pm Post subject: |
|
|
It's not on the wiki, but there is a second "signed" parameter for the read integer functions.
"celua.txt": Quote: | readSmallInteger, readInteger, readSmallIntegerLocal, readIntegerLocal
can also have second boolean parameter. If true, value will be signed. |
_________________
|
|
Back to top |
|
|
fakuivan Newbie cheater Reputation: 0
Joined: 27 Dec 2018 Posts: 17
|
Posted: Thu Jan 24, 2019 3:41 pm Post subject: |
|
|
TheyCallMeTim13 wrote: | It's not on the wiki, but there is a second "signed" parameter for the read integer functions.
"celua.txt": Quote: | readSmallInteger, readInteger, readSmallIntegerLocal, readIntegerLocal
can also have second boolean parameter. If true, value will be signed. |
|
Yes, that's an option but it won't work for small jumps, where I use readByes
|
|
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
|
|