
![]() |
vsloathe
A little background - I'm writing a bot for a game. Auto-leveling type bot not to use, but because I see a pretty big niche and think I can sell it.
So I have a memory reading library that lets me open up the memory of any process handle (as long as I run it with admin privs obviously). The library lets me read the data from one memory address at a time, so here is my dilemma: Due to DMA, the memory address of some of the data I want changes with every instance of the game (every time you relog or reopen the game). I can go through the memory and manually get the address each time with a program like CheatEngine or TSearch, but the problem is that this obviously isn't going to work, since I can't have the user manually search for the addresses each time...I was wondering if anyone had any idea how to loop through a memory region and search for a particular "known", and grab the address? If I have the address of one part of the memory region, I have everything, since the structure in memory stays the same, the base address just changes. Thanks, -V m0nkeymafia
do you know what to look for as the pattern of the start of the memory you want?
i dont know the start address of memory location, but you could try loop through all memory [starting from the start] and then try match the data there with the pattern your looking for. you could alternatively allocate a big lump of memory then iterate backwards, but thats nasty. thats all i can come up with lol, im sure someone else has a better idea ![]() perkiset
dunno about a better idea... it is sort of a virus-scanner approach. Don't know how else you could do it, really.
nop_90
I have been out of the scene for ages.
i am guessing u are using the MS debug API to read the memory. but a good place to start is here http://win32assembly.online.fr/ tutorials.htmlto allow the segments of the written to you have to change the flags in the PE header, (you can change segment to read/write/exe etc) since memory is mapped virtual memory => physical the technique i saw was to set index register to address start approx to scan. wrap in exception handler like show here http://win32assembly.online.fr/Exceptionhandling.html then scan for bytes, if crashes assembler exception handler catches it, advance set ammount of bytes (2000 lets say) repeat. a good place to start is here http://www.woodmann.com/forum/ Investigate the legality of what u are doing ![]() Strange that law authorities seem to be more concerned of guys who release cracks etc, then people who make child porn, process the payments for child porn etc. i guess child porn does not affect buisness intrests vsloathe
As far as I know it's legal, or at least in a legal gray area (they could sue, but you hire a lawyer to write your ToS and make sure that you can legally say "all copyrights owned by so and so, I'm not responsible for what users of the software do, you can't use this if you work for so and so"
![]() Anyway, the library I am using has a function to set the debug level so I would assume that it hooks MS's debug API. The memory read function looks like this: _MemoryRead($address,$DLLHandle,[$type=dword]) It returns data in the format specified in $type (int, bool, float, char, decimal dword) from $address using the process handle to an opened section of memory $DLLHandle. Usually I am looking for a known number, like for instance mana (I can actually OCR the points of mana or HP from the screen but it's slow) - so I scan for that number, record addresses that have it in an array, cast a spell, and then loop through the array to see which addresses contain data that changed...so on and so forth until I have the address for mana. The address for health is then [mana address] - 0x4 (4 hex bytes). The problem with looping through and scanning the memory is that it takes SO LONG so I was wondering if anyone knew a way to do it faster. vsloathe
I have part of my solution worked out so I'll post it here. The code might look a little convoluted to some of you because it's written in AutoItScript. I've been using AutoItScript for bot development because it's so well suited to that purpose (lots of really finite control over windows and objects without having to get my hands too dirty, and good ability to plug in COM objects too).
Here goes: Const $uniquePatternOffset=0x374 Const $uniquePatternValue=0x007D0A7C Const $uniquePatternOffset2=4 Const $uniquePatternValue2=3 Const $CurrentHealthOffset=0x4c0 Const $MaxHealthOffset=0x4D8 Const $CurrentManaOffset=0x4c4 Const $MaxManaOffset=0x4Dc Const $OffsetSearchStep=0x1000 Const $maxSearchableMemory=0x70000000 Const $startSearchableMemory=0x400000 HotKeySet("^+!{ESC}","Abort" ![]() SetPrivilege("SeDebugPrivilege", 1) $handle = _MemOpen() $offsets=findplayerdataoffset($handle) Func findplayerdataoffset($handle) $ba seOffset=$startSearchableMemory$ba seOffset+=$uniquePatternOffset$timerStart=TimerInit() TrayTip("Begin Search. ","Looking for base offset.",2,1) While $ba seOffset<$maxSearchableMemory$value=_WoWMemRead($ba seOffset,$handle,'dword')If $value=$uniquePatternValue Then If _WoWMemRead($ba seOffset-$uniquePatternOffset2,$handle,'dword')=$uniquePatternValue2 Then$ba seOffset-=$uniquePatternOffset ; Found our offset. Put offset back to xxxxx000TrayTip("Found Location. ",Hex($ba seOffset)&" "&Floor(TimerDiff($timerStart)/1000)&" seconds.",2,1)Dim $dataarray $dataarray=_ArrayCreate($ba seOffset+$CurrentHealthOffset,$baseOffset+$MaxHealthOffset,$baseOffset+$CurrentManaOffset,$baseOffset+$MaxManaOffset)Return $dataarray ExitLoop EndIf EndIf $ba seOffset+=$OffsetSearchStepWEnd EndFunc _MemClose($handle) A couple of the functions like _MemClose() and _MemOpen() are just reusable pieces I wrote so I wouldn't have to go through the headache of changing the text by which the process handle is gotten should the game developer ever decide to change it (which they frequently do), but merely change the value of one global variable. Anyway, it might seem unintelligible to you, and I myself have trouble understanding memory addressing and pointers at times still, but that's what I've come up with so far. That returns the player's health, max health, mana, and max mana. I'm now working on returning all objects near the player (monsters to kill) in an array, because I already can rotate the player towards a location using some math functions and the data on each monster contains its XYZ coords. EDIT: forgot to make it actually do something. vsloathe
Cool, I figured out that the base array pointer that contains the PlayerID is 0x468 hex bytes up from the location of the "known" that my scanner locates.
I've roughly identified the location of some components of the memory struct that contains player data like so (add each offset to the location of the base pointer, 0x468 bytes up from the known that I locate): +0x00 player ID - 8 bytes integer +0x10 - x - float +0x14 - y - float +0x18 - z - float +0x1C - horizontal direction - float (0 ... 2*PI) +0x20 - vertical direction - float (-PI/2 ... PI/2) +0x30 ->(4 bytes address, pointer to another structure) +0x58 health - 4 bytes integer +0x30 -> +0x5C mana - 4 bytes integer +0x40 target ID - 8 bytes integer +0x58 health - 4 bytes integer +0x5C mana - 4 bytes integer In case anyone is interested. I think I can do a decent job of finding monsters to kill using the target ID. m0nkeymafia
nice one dude good find!
vsloathe
Yeah by the time I'm done this I'm going to be the resident expert on game memory reading. lol
|

Thread Categories

![]() |
![]() |
Best of The Cache Home |
![]() |
![]() |
Search The Cache |
- Ajax
- Apache & mod_rewrite
- BlackHat SEO & Web Stuff
- C/++/#, Pascal etc.
- Database Stuff
- General & Non-Technical Discussion
- General programming, learning to code
- Javascript Discussions & Code
- Linux Related
- Mac, iPhone & OS-X Stuff
- Miscellaneous
- MS Windows Related
- PERL & Python Related
- PHP: Questions & Discussion
- PHP: Techniques, Classes & Examples
- Regular Expressions
- Uncategorized Threads