crazedwombat Posted May 10, 2009 Share Posted May 10, 2009 (edited) Here's my CE table for the value i want to calculate...<CheatTable> <CheatEntries> <CheatEntry> <Description>hp</Description> <Address>00000000</Address> <Type>2</Type> <Pointer> <Offsets> <Offset>0278</Offset> <Offset>0028</Offset> </Offsets> <Address>009E7C8C</Address> <InterpretableAddress>ElementClient.exe+005E7C8C</InterpretableAddress> </Pointer> </CheatEntry> </CheatEntries></CheatTable>and a representation of how it appears in CE in order from top to bottom:29E99288 <target addressaddress of pointer.......033C2030...............................offset(hex) 278address of pointer....ElementClient.exe+005E7C8C...offset(hex) 28I have a general understanding that the Element line points to the next one up, then the next one up points to the target...I've searched and found and modified this example but i can't get it to work:while 1$baseADDR = _MemoryGetBaseAddress($ProcessID, 1);;gets the base address after finding the ID$StaticOffset = Dec("005E7C8C");;the offset for the green address$CharHPPtrOffset = "278";;2nd level pointer offset$CharHPOffset = "28";;1st level pointer offset$CalcADDR = "0x" & Hex($baseADDR + $StaticOffset);;2nd level pointer$value = "0x" & Hex(_MemoryRead($CalcADDR,$ProcessID));;calc to find 1st level pointer$CalcADDR = "0x" & Hex($value + $CharHPPtrOffset);;1st level pointer$value = "0x" & Hex(_MemoryRead($CalcADDR,$ProcessID));;calc to find address of value$HPADDR = "0x" & Hex($value + $CharHPOffset);;address of value$HP = _MemoryRead($HPADDR,$ProcessID);;the value tooltip($HP,0,0)tooltip($baseADDR,0,100)wendThis reports 0 for both which is the wrong value.......... if i replace everything from while to wend with this:while 1$hp = _MemoryRead(0x29E99288, $DllInformation)tooltip($HP,0,0)wendit DOES work... so it has to be the code from above going wrong.. seems it fails from the first baseADDR, and i don't know why... i included the memory udf and everything... from http://www.autoitscript.com/forum/index.ph...ic=78834&hlPLEASE HELP..PS i've tried swapping the 28 and 278 to no avail.For those that really want to dig in, here's the script in entirety... "getbase.au3" is the memory.au3 from the above listed thread..#include <NomadMemory.au3>#include <getbase.au3>HotKeySet("{PAUSE}", "Pause")HotKeySet("^c", "MyExit")Hotkeyset("^f", "Forage")Opt("WinTitleMatchMode", 4)Opt("TrayIconDebug",1)Global $ProcessID = WinGetProcess("ClassName=XYElementClient Window","")If $ProcessID = -1 Then MsgBox(4096, "ERROR", "Failed to detect ESO window.")EndIfGlobal $DllInformation = _MemoryOpen($ProcessID)Global $PauseGlobal $Foragewhile 1$baseADDR = _MemoryGetBaseAddress($ProcessID, 1);;gets the base address after finding the ID$StaticOffset = Dec("28");;the offset for the green address$CharHPPtrOffset = "278";;2nd level pointer offset$CharHPOffset = "005E7C8C";;1st level pointer offset$CalcADDR = "0x" & Hex($baseADDR + $StaticOffset);;2nd level pointer$value = "0x" & Hex(_MemoryRead($CalcADDR,$ProcessID));;calc to find 1st level pointer$CalcADDR = "0x" & Hex($value + $CharHPPtrOffset);;1st level pointer$value = "0x" & Hex(_MemoryRead($CalcADDR,$ProcessID));;calc to find address of value$HPADDR = "0x" & Hex($value + $CharHPOffset);;address of value$HP = _MemoryRead($HPADDR,$ProcessID);;the value tooltip($HP,0,0)tooltip($baseADDR,0,100)sleep(500)WEndFunc Pause() $Pause = NOT $Pause While $Pause Sleep(5000) WEndwinactivate("口袋西游")WinWaitActive("口袋西游")send("{ESC}")EndFuncFunc Forage() $Forage = NOT $Forage while $Forage winactivate("口袋西游") WinWaitActive("口袋西游") mouseclick("LEFT",407, 365,1) sleep(25000) WEndEndFuncFunc MyExit()_MemoryClose($DllInformation)If @Error Then MsgBox(4096, "ERROR", "Failed to close memory.") ExitEndIfEndFunc Edited May 10, 2009 by crazedwombat Link to comment Share on other sites More sharing options...
Qousio Posted May 10, 2009 Share Posted May 10, 2009 Here's my CE table for the value i want to calculate...<CheatTable> <CheatEntries> <CheatEntry> <Description>hp</Description> <Address>00000000</Address> <Type>2</Type> <Pointer> <Offsets> <Offset>0278</Offset> <Offset>0028</Offset> </Offsets> <Address>009E7C8C</Address> <InterpretableAddress>ElementClient.exe+005E7C8C</InterpretableAddress> </Pointer> </CheatEntry> </CheatEntries></CheatTable>and a representation of how it appears in CE in order from top to bottom:29E99288 <target addressaddress of pointer.......033C2030...............................offset(hex) 278address of pointer....ElementClient.exe+005E7C8C...offset(hex) 28I have a general understanding that the Element line points to the next one up, then the next one up points to the target...I've searched and found and modified this example but i can't get it to work:while 1$baseADDR = _MemoryGetBaseAddress($ProcessID, 1);;gets the base address after finding the ID$StaticOffset = Dec("005E7C8C");;the offset for the green address$CharHPPtrOffset = "278";;2nd level pointer offset$CharHPOffset = "28";;1st level pointer offset$CalcADDR = "0x" & Hex($baseADDR + $StaticOffset);;2nd level pointer$value = "0x" & Hex(_MemoryRead($CalcADDR,$ProcessID));;calc to find 1st level pointer$CalcADDR = "0x" & Hex($value + $CharHPPtrOffset);;1st level pointer$value = "0x" & Hex(_MemoryRead($CalcADDR,$ProcessID));;calc to find address of value$HPADDR = "0x" & Hex($value + $CharHPOffset);;address of value$HP = _MemoryRead($HPADDR,$ProcessID);;the value tooltip($HP,0,0)tooltip($baseADDR,0,100)wendThis reports 0 for both which is the wrong value.......... if i replace everything from while to wend with this:while 1$hp = _MemoryRead(0x29E99288, $DllInformation)tooltip($HP,0,0)wendit DOES work... so it has to be the code from above going wrong.. seems it fails from the first baseADDR, and i don't know why... i included the memory udf and everything... from http://www.autoitscript.com/forum/index.ph...ic=78834&hlPLEASE HELP..PS i've tried swapping the 28 and 278 to no avail.For those that really want to dig in, here's the script in entirety... "getbase.au3" is the memory.au3 from the above listed thread..#include <NomadMemory.au3>#include <getbase.au3>HotKeySet("{PAUSE}", "Pause")HotKeySet("^c", "MyExit")Hotkeyset("^f", "Forage")Opt("WinTitleMatchMode", 4)Opt("TrayIconDebug",1)Global $ProcessID = WinGetProcess("ClassName=XYElementClient Window","")If $ProcessID = -1 Then MsgBox(4096, "ERROR", "Failed to detect ESO window.")EndIfGlobal $DllInformation = _MemoryOpen($ProcessID)Global $PauseGlobal $Foragewhile 1$baseADDR = _MemoryGetBaseAddress($ProcessID, 1);;gets the base address after finding the ID$StaticOffset = Dec("28");;the offset for the green address$CharHPPtrOffset = "278";;2nd level pointer offset$CharHPOffset = "005E7C8C";;1st level pointer offset$CalcADDR = "0x" & Hex($baseADDR + $StaticOffset);;2nd level pointer$value = "0x" & Hex(_MemoryRead($CalcADDR,$ProcessID));;calc to find 1st level pointer$CalcADDR = "0x" & Hex($value + $CharHPPtrOffset);;1st level pointer$value = "0x" & Hex(_MemoryRead($CalcADDR,$ProcessID));;calc to find address of value$HPADDR = "0x" & Hex($value + $CharHPOffset);;address of value$HP = _MemoryRead($HPADDR,$ProcessID);;the value tooltip($HP,0,0)tooltip($baseADDR,0,100)sleep(500)WEndFunc Pause() $Pause = NOT $Pause While $Pause Sleep(5000) WEndwinactivate("口袋西游")WinWaitActive("口袋西游")send("{ESC}")EndFuncFunc Forage() $Forage = NOT $Forage while $Forage winactivate("口袋西游") WinWaitActive("口袋西游") mouseclick("LEFT",407, 365,1) sleep(25000) WEndEndFuncFunc MyExit()_MemoryClose($DllInformation)If @Error Then MsgBox(4096, "ERROR", "Failed to close memory.") ExitEndIfEndFuncI'm assuming you need to find the pointer of an address? Any kernel debugger is capable of this. Even Cheat Engine. Link to comment Share on other sites More sharing options...
crazedwombat Posted May 10, 2009 Author Share Posted May 10, 2009 (edited) I'm assuming you need to find the pointer of an address? Any kernel debugger is capable of this. Even Cheat Engine.i have the pointer.. that's the point... i can't get autoit to calculate the pointers... i don't want to cut and paste from CE every time i restart the game... and i don't want to use some old convoluted 50000 step code to do it... i heard tihs memory.au3 works but i can't figure out the syntax i guess...Maybe understanding the equation will help me, is it like this?29E99288 <target addressaddress of pointer.......033C2030...............................offset(hex) 278address of pointer....ElementClient.exe+005E7C8C...offset(hex) 28elementclient.exe+005E7C8C+28=033C2030then033C2030+278=29E99288??????????????????????????????????????????????? Edited May 10, 2009 by crazedwombat Link to comment Share on other sites More sharing options...
Qousio Posted May 10, 2009 Share Posted May 10, 2009 i have the pointer.. that's the point... i can't get autoit to calculate the pointers... i don't want to cut and paste from CE every time i restart the game... and i don't want to use some old convoluted 50000 step code to do it... i heard tihs memory.au3 works but i can't figure out the syntax i guess...Maybe understanding the equation will help me, is it like this?29E99288 <target addressaddress of pointer.......033C2030...............................offset(hex) 278address of pointer....ElementClient.exe+005E7C8C...offset(hex) 28elementclient.exe+005E7C8C+28=033C2030then033C2030+278=29E99288???????????????????????????????????????????????Did you try using NomadMemory.au3 ?And if you just want the pointers to be loaded on startup, create an .ini file, and make autoit load the values. Link to comment Share on other sites More sharing options...
crazedwombat Posted May 10, 2009 Author Share Posted May 10, 2009 Did you try using NomadMemory.au3 ?And if you just want the pointers to be loaded on startup, create an .ini file, and make autoit load the values.yeah i am using nomadmemory......... i have no problem reading memory... my problem is scripting autoit to calculate the pointers so i don't have to manually enter them every time Link to comment Share on other sites More sharing options...
Diception Posted May 11, 2009 Share Posted May 11, 2009 after working with a similar script and memorygetbase myself for about a month with no success i just found the base address which has only changed in pwi once in the last 6 months with the physical base i then use offsets and build from there and like i said ive only had to change that base once. ill post and example of my ini after work. (not on home pc) Link to comment Share on other sites More sharing options...
FreeFry Posted May 11, 2009 Share Posted May 11, 2009 (edited) It's funny, I was working with a mate on doing memory reading - which also includes 'hooking' (by injecting bytecode into the process), and I wrote a few functions to help with this. (there're not in a UDF format - from what I know): expandcollapse popup; Writing. Quite simple: Pass it a handle to the process(obtained from the _WinAPI_OpenProcess function), the address to write to, the data you wanna write, and the data type(if other than byte). Func _WriteProcessMemory(ByRef $hvProcess, $ivAddress, $bvData, $svDataType = "byte") Local $stvWritten = DllStructCreate("int Written") Local $stvData = DllStructCreate($svDataType) DllStructSetData($stvData, 1, $bvData) Local $avResult = DllCall("Kernel32.dll", "int", "WriteProcessMemory", "int", $hvProcess, "int", $ivAddress, "ptr", DllStructGetPtr($stvData), "int", DllStructGetSize($stvData), "int", DllStructGetPtr($stvWritten)) Return(SetError($avResult[0], 0, DllStructGetData($stvWritten, "Written"))) EndFunc ; Simplified reading of memory(never used nomad memory or any of those others so I dunno how 'user-friendly' they are). Pass it a handle of the process(obtained through _WinAPI_OpenProcess), the address to read from, and the data type(if other than byte), and it'll return the value directly. Func _ReadProcessMemory(ByRef $hvProcess, $ivAddress, $svDataType = "byte") Local $stvRead = DllStructCreate("int Read") Local $stvData = DllStructCreate($svDataType) Local $avResult = DllCall("Kernel32.dll", "int", "ReadProcessMemory", "int", $hvProcess, "int", $ivAddress, "ptr", DllStructGetPtr($stvData), "int", DllStructGetSize($stvData), "ptr", DllStructGetPtr($stvRead)) Return(SetError(Not $avResult[0], DllStructGetData($stvRead, "Read"), DllStructGetData($stvData, 1))) EndFunc ; This, from what I can tell does the same (and more if needed) that which the MemoryGetBaseAddress function does. Just give it the process id, and the main executable module name of the game, module name, ex: "ElementClient.exe")) Func _ProcessGetModuleBase($ivPID, $svModuleName) $ivPID = ProcessExists($ivPID) If Not $ivPID Then Return(SetError(1, 0, 0)); Process does not exist Local Const $TH32CS_SNAPMODULE = 0x00000008 Local Const $sMODULEENTRY32Struct = "dword Size;" & _ "dword 32ModuleID;" & _ "dword 32ProcessID;" & _ "dword GlblcntUsage;" & _ "dword ProccntUsage;" & _ "ptr modBaseAddr;" & _ "dword modBaseSize;" & _ "hwnd hModule;" & _ "char Module[255];" & _ "char ExePath[260]" Local $hvSnapShot = DllCall("Kernel32.dll", "hwnd", "CreateToolhelp32Snapshot", "dword", $TH32CS_SNAPMODULE, "dword", $ivPID) If Not $hvSnapShot[0] Then Return(SetError(2, 0, 0)); Could not create snapshot? Local $stMODULEENTRY32 = DllStructCreate($sMODULEENTRY32Struct) DllStructSetData($stMODULEENTRY32, "Size", DllStructGetSize($stMODULEENTRY32)) Local $ivState = DllCall("Kernel32.dll", "int", "Module32First", "hwnd", $hvSnapShot[0], "long_ptr", DllStructGetPtr($stMODULEENTRY32)) If Not $ivState[0] Then Return(SetError(3, _WinAPI_CloseHandle($hvSnapShot[0]), 0)); Could not enumerate first module in list? Local $ivRet = 0 Local $svModule Do $ivRet = DllStructGetData($stMODULEENTRY32, "modBaseAddr") $svModule = DllStructGetData($stMODULEENTRY32, "Module") If $svModule = $svModuleName Then ExitLoop $ivState = DllCall("Kernel32.dll", "int", "Module32Next", "hwnd", $hvSnapShot[0], "long_ptr", DllStructGetPtr($stMODULEENTRY32)) Sleep(1) Until Not $ivState[0] _WinAPI_CloseHandle($hvSnapShot[0]) Return $ivRet EndFunc ; This will help in reading pointers: pass it a handle(same as with write and read funtions) to the process, the address of the base pointer, and the offset(s). ; The offset has to be passed as an array(this is due to multi-level pointers), basically, it just reads the value from the first pointer, then reads from the value it got+offset, then it does that for every offset. ; Which in the end returns the address the last offset through the pointer+offsets leads it to. Func _ReadProcessPointers(ByRef $hvProcess, $ivBaseAddress, $avOffsets) If Not IsArray($avOffsets) Then Return _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr") $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr") For $i = 0 To UBound($avOffsets)-1 $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets[$i], "ptr") Next Return $ivBaseAddress EndFunc Also, offsets in cheat engine, is in hex, doing Dec("12") will not return the correct value, you need to do Dec("0x12"). And preferably use Number instead of Dec, as the Dec function is supposed to convert numbers to decimal not strings, while Number converts from strings to a number(obviously), otherwise Dec will first call Number to first convert it into a number, then Dec will run(so basically you're running two instructions when you only have to run one). I don't know if this will solve your problem or anything, but the main issue I think is that you're doing Dec("12"), instead of Number("0x12"), but why not just give it in hex value directly? Edit: Also, pointers work like this: Base pointer = static pointer, or pointer that points to the 'correct' address all the time(correct being the address you want/need it to point to). if you read the value that the address the base pointer is located at(as a ptr), it will give you the address to some other pointer(or directly to the address you're after), if it's a multi-level pointer, adding/subtracting the offset to/from the value you read from the base pointer will give you the next pointer address. So: SecondPointer = readmemory(BasePointer+offset) ThirdPointer = readmemory(SecondPointer+offset) HealthAddress = ThirdPointer+offset HealthValue = readmemory(HealthAddress) I hope that makes sense.. Edited May 11, 2009 by FreeFry Link to comment Share on other sites More sharing options...
Diception Posted May 11, 2009 Share Posted May 11, 2009 (edited) code removed Edited May 12, 2009 by Diception Link to comment Share on other sites More sharing options...
Diception Posted May 11, 2009 Share Posted May 11, 2009 sorry code box doesnt like me today p.s. above code will be removed in 12 hours Link to comment Share on other sites More sharing options...
FreeFry Posted May 11, 2009 Share Posted May 11, 2009 Ugh. it's [ code] and [ /code] Also, how is posting a huge script supposed to help him? If it contains something to point him in the right direction, why not just post that part?. Link to comment Share on other sites More sharing options...
Diception Posted May 12, 2009 Share Posted May 12, 2009 if you watched my first post i said that what he was doing is a dead road for what he wants. the code that i posted will help him understand a working path.its code i found in these forums that i adapted and learned from. in other words it is allready posted inthese forums thats all. Link to comment Share on other sites More sharing options...
FreeFry Posted May 12, 2009 Share Posted May 12, 2009 You said you were going to post an example, not a 1000+ line script... In my opinion that will only make him more confused, unless he really wants to spend time to understand the whole of the script. Maybe an explanation of what it does, and how it works would be in order(examples are complementary with a description you know ). Link to comment Share on other sites More sharing options...
Diception Posted May 12, 2009 Share Posted May 12, 2009 (edited) point taken and i can agree i know for some a working copy is good enough i need to look under the hood to be happy Global $APP_BASE_ADDRESS = "0x" & Hex(IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_BASEADDRESS_ROOT_KEY, $CFG_BASEADDRESS_KEY, "9885820"));instead of lalala+45678 use the 0x123456 actual address Global $PROCESS_INFORMATION = _MemoryOpen($PROCESS_ID) Global $OFFSET_AT[3] $OFFSET_AT[1] = 32 $OFFSET_AT[2] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_AT, "2648") Global $OFFSET_MP[3], $OFFSET_MAX_MP[3] $OFFSET_MP[1] = 32 $OFFSET_MP[2] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_MP, "1128") $OFFSET_MAX_MP[1] = 32 $OFFSET_MAX_MP[2] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_MAXMP, "1176") Global $OFFSET_HP[3], $OFFSET_MAX_HP[3] $OFFSET_HP[1] = 32 $OFFSET_HP[2] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_HP, "1124") $OFFSET_MAX_HP[1] = 32 $OFFSET_MAX_HP[2] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_MAXHP, "1172") $LABEL_OFFSETH_HP = GUICtrlCreateLabel("Hex: " & Hex($OFFSET_HP[2]), 80, 370, 85, 20) Edited May 12, 2009 by Diception Link to comment Share on other sites More sharing options...
FreeFry Posted May 12, 2009 Share Posted May 12, 2009 the lalala part of "lalala+45678" is part of the module allocation base, this CAN differ from system to system, so resolving lalala to an actual address is good procedure(otherwise a static address might not be static if you use a direct address, instead of an offset one). also, reading pointers can be very easy if one use the _ReadProcessPointers helper function that i posted earlier: Say you have a base pointer which you want to use to resolve the address of your health for example, and that this pointer is located at game.exe+1234: We then we define a variable which contains that address(can be simplified with my _ProcessGetModuleBase function), and then use the _ReadProcessPointers function to resolve the pointer to the address we're after: #include <WinAPI.au3> #include <Constants.au3> Dim $iPID = ProcessExist("game.exe"); We should store this, as we'll be using it later Dim $iHealthBasePtr = _ProcessGetModuleBase($iPID, "game.exe")+0x1234; Find the allocation base(address) of game.exe and add the offset the pointer is at to that Dim $aHealthPtrOffsets[2] = [0x54, 0x10]; This would be for a 3 level pointer(first pointer is the base pointer), second pointer offset = 0x54, third = 0x10 Dim $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, 0, $iPID, 0); Get a handle to the process Dim $iHealthAddress = _ReadProcessPointers($hProcess, $iHealthBasePtr, $aHealthPtrOffsets); This will resolve the absolute address of the Health address from the base pointer + offsets Dim $iHealth While 1 $iHealth = _ReadProcessMemory($hProcess, $iHealthAddress, "float"); Read the health as a float(for example, if the health where stored as a dword, just specify dword as Data-type ; Do something based on what your health is Sleep(250) WEnd Func _ReadProcessPointers(ByRef $hvProcess, $ivBaseAddress, $avOffsets) If Not IsArray($avOffsets) Then Return _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr") $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress, "ptr") For $i = 0 To UBound($avOffsets)-1 $ivBaseAddress = _ReadProcessMemory($hvProcess, $ivBaseAddress+$avOffsets[$i], "ptr") Next Return $ivBaseAddress EndFunc Func _ReadProcessMemory(ByRef $hProcess, $pBaseAddress, $svDataType = "byte") Local $stRead = DllStructCreate("int Read") Local $stData = DllStructCreate($svDataType) Local $aResult = DllCall("Kernel32.dll", "int", "ReadProcessMemory", "int", $hProcess, "int", $pBaseAddress, "ptr", DllStructGetPtr($stData), "int", DllStructGetSize($stData), "ptr", DllStructGetPtr($stRead)) Return(SetError(Not $aResult[0], DllStructGetData($stRead, "Read"), DllStructGetData($stData, 1))) EndFunc Pseudo code, not tested(the functions work though ^^) Link to comment Share on other sites More sharing options...
Diception Posted May 12, 2009 Share Posted May 12, 2009 nice yours looks straight forward i'll look at using it in future code when i get a chance. probly this weekend until then good hunting Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now