Memory Scanning: The Wrong Approach. menu

User Tag List

Results 1 to 10 of 10
  1. #1
    raindog's Avatar Active Member
    Reputation
    68
    Join Date
    Dec 2007
    Posts
    51
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Memory Scanning: The Wrong Approach.

    In my experience with wow, Memory Scanning to find offsets, etc is only limited in usefulness. To get the real understanding of wow, one needs to do some actual reverse engineering.

    I'll walk you guys through how to get the ID of the current player. The function in wow is called ClntObjMgrGetActivePlayer.

    Since wow uses Lua, it makes things worlds easier to find functions. In this case I will use GetPlayerMapPosition simply because it was the first function that came up in IDA strings window =). Double clicking on the string gives is this:

    Code:
    .rdata:00887220 aGetplayermappo db 'GetPlayerMapPosition',0 ; DATA XREF: .data:00B76FA0o
    Following the refence gives us:

    Code:
    .data:00B76FA0                 dd offset aGetplayermappo ; "GetPlayerMapPosition"
    .data:00B76FA4                 dd offset sub_4AFDD0
    following sub_4AFDD0 we get

    Code:
    .text:004AFDD0 sub_4AFDD0      proc near               ; DATA XREF: .data:00B76FA4o
    .text:004AFDD0
    .text:004AFDD0 var_1C          = qword ptr -1Ch
    .text:004AFDD0 var_10          = dword ptr -10h
    .text:004AFDD0 var_C           = dword ptr -0Ch
    .text:004AFDD0 var_8           = dword ptr -8
    .text:004AFDD0 var_4           = dword ptr -4
    .text:004AFDD0 arg_0           = dword ptr  8
    .text:004AFDD0
    .text:004AFDD0                 push    ebp
    .text:004AFDD1                 mov     ebp, esp
    .text:004AFDD3                 sub     esp, 10h
    .text:004AFDD6                 push    esi
    .text:004AFDD7                 mov     esi, [ebp+arg_0]
    .text:004AFDDA                 push    1
    .text:004AFDDC                 push    esi
    .text:004AFDDD                 call    sub_70E7B0
    .text:004AFDE2                 add     esp, 8
    .text:004AFDE5                 test    eax, eax
    .text:004AFDE7                 jnz     short loc_4AFDFE
    .text:004AFDE9                 push    offset aUsageGetplayer ; "Usage: GetPlayerMapPosition(\"player\")"
    .text:004AFDEE                 push    esi
    .text:004AFDEF                 call    sub_70FF00
    .text:004AFDF4                 add     esp, 8
    .text:004AFDF7                 xor     eax, eax
    .text:004AFDF9                 pop     esi
    .text:004AFDFA                 mov     esp, ebp
    .text:004AFDFC                 pop     ebp
    .text:004AFDFD                 retn
    .text:004AFDFE ; ---------------------------------------------------------------------------
    .text:004AFDFE
    .text:004AFDFE loc_4AFDFE:                             ; CODE XREF: sub_4AFDD0+17j
    .text:004AFDFE                 fldz
    .text:004AFE00                 push    0
    .text:004AFE02                 push    1
    .text:004AFE04                 fst     [ebp+var_4]
    .text:004AFE07                 push    esi
    .text:004AFE08                 fstp    [ebp+var_8]
    .text:004AFE0B                 call    sub_70E930
    .text:004AFE10                 push    eax             ; Str1
    .text:004AFE11                 call    sub_53C500
    .text:004AFE16                 add     esp, 10h
    .text:004AFE19                 mov     [ebp+var_10], eax
    .text:004AFE1C                 mov     [ebp+var_C], edx
    .text:004AFE1F                 call    ClntObjMgrGetActivePlayer
    .text:004AFE24                 cmp     [ebp+var_10], eax
    .text:004AFE27                 jnz     short loc_4AFE2E
    .text:004AFE29                 cmp     [ebp+var_C], edx
    .text:004AFE2C                 jz      short loc_4AFE4E
    .text:004AFE2E
    .text:004AFE2E loc_4AFE2E:                             ; CODE XREF: sub_4AFDD0+57j
    .text:004AFE2E                 lea     eax, [ebp+var_10]
    .text:004AFE31                 push    eax
    .text:004AFE32                 call    sub_4B4F30
    .text:004AFE37                 add     esp, 4
    .text:004AFE3A                 test    eax, eax
    .text:004AFE3C                 jnz     short loc_4AFE4E
    .text:004AFE3E                 lea     ecx, [ebp+var_10]
    .text:004AFE41                 push    ecx
    .text:004AFE42                 call    sub_4B6BF0
    .text:004AFE47                 add     esp, 4
    .text:004AFE4A                 test    eax, eax
    .text:004AFE4C                 jz      short loc_4AFE66
    .text:004AFE4E
    .text:004AFE4E loc_4AFE4E:                             ; CODE XREF: sub_4AFDD0+5Cj
    .text:004AFE4E                                         ; sub_4AFDD0+6Cj
    .text:004AFE4E                 mov     ecx, [ebp+var_C]
    .text:004AFE51                 lea     edx, [ebp+var_8]
    .text:004AFE54                 push    edx
    .text:004AFE55                 mov     edx, [ebp+var_10]
    .text:004AFE58                 lea     eax, [ebp+var_4]
    .text:004AFE5B                 push    eax
    .text:004AFE5C                 push    ecx
    .text:004AFE5D                 push    edx
    .text:004AFE5E                 call    sub_4AEDC0
    .text:004AFE63                 add     esp, 10h
    .text:004AFE66
    .text:004AFE66 loc_4AFE66:                             ; CODE XREF: sub_4AFDD0+7Cj
    .text:004AFE66                 fld     [ebp+var_4]
    .text:004AFE69                 sub     esp, 8
    .text:004AFE6C                 fstp    [esp+1Ch+var_1C]
    .text:004AFE6F                 push    esi             ; int
    .text:004AFE70                 call    sub_70EAE0
    .text:004AFE75                 fld     [ebp+var_8]
    .text:004AFE78                 add     esp, 4
    .text:004AFE7B                 fstp    [esp+1Ch+var_1C]
    .text:004AFE7E                 push    esi             ; int
    .text:004AFE7F                 call    sub_70EAE0
    .text:004AFE84                 add     esp, 0Ch
    .text:004AFE87                 mov     eax, 2
    .text:004AFE8C                 pop     esi
    .text:004AFE8D                 mov     esp, ebp
    .text:004AFE8F                 pop     ebp
    .text:004AFE90                 retn
    .text:004AFE90 sub_4AFDD0      endp
    Now at this point we should know that somewhere in this function, it has to get a pointer to the player object, otherwise how else will it find the position of the player? So what we can do is follow the functions in this code to see what they look like. From experience I know that the sub_70xxxx functions are lua api calls. The first interesting function we see is this:

    Code:
    .text:0053C500 ; int __cdecl sub_53C500(char *Str1)
    .text:0053C500 sub_53C500      proc near               ; CODE XREF: sub_49CD80+22p
    .text:0053C500                                         ; sub_49CE20+46p ...
    .text:0053C500
    .text:0053C500 var_8           = dword ptr -8
    .text:0053C500 var_4           = dword ptr -4
    .text:0053C500 Str1            = dword ptr  8
    .text:0053C500
    .text:0053C500                 push    ebp
    .text:0053C501                 mov     ebp, esp
    .text:0053C503                 sub     esp, 8
    .text:0053C506                 mov     ecx, [ebp+Str1]
    .text:0053C509                 xor     eax, eax
    .text:0053C50B                 push    eax             ; char
    .text:0053C50C                 mov     [ebp+var_8], eax
    .text:0053C50F                 mov     [ebp+var_4], eax
    .text:0053C512                 lea     eax, [ebp+var_8]
    .text:0053C515                 push    eax             ; int
    .text:0053C516                 push    ecx             ; Str1
    .text:0053C517                 call    sub_53B620
    .text:0053C51C                 mov     eax, [ebp+var_8]
    .text:0053C51F                 mov     edx, [ebp+var_4]
    .text:0053C522                 add     esp, 0Ch
    .text:0053C525                 mov     esp, ebp
    .text:0053C527                 pop     ebp
    .text:0053C528                 retn
    .text:0053C528 sub_53C500      endp
    Lets trace that call and we see a really interesting function which appears to take an 8 byte value by reference (determined after analysis).

    That function has a bunch of strcmp calls that look something like this:

    Code:
    .text:0053B66A                 push    6               ; MaxCount
    .text:0053B66C                 push    offset aPlayer_0 ; "player"
    .text:0053B671                 push    edi             ; Str1
    .text:0053B672                 mov     [ebp+var_58], edi
    
    .text:0053B6A4                 push    3               ; MaxCount
    .text:0053B6A6                 push    offset aPet_1   ; "pet"
    .text:0053B6AB                 push    edi             ; Str1
    .text:0053B6AC                 call    sub_63A480
    
    .text:0053B6E9                 push    6               ; MaxCount
    .text:0053B6EB                 push    offset aTarget  ; "target"
    .text:0053B6F0                 push    edi             ; Str1
    .text:0053B6F1                 call    sub_63A480
    From this it appears that we want to follow the logic when "player" is passed to this function. Following the logic is a tough problem here, but eventually you will see a qword value placed on the stack and then used after the function call like so:

    Code:
    .text:0053C517                 call    sub_53B620
    .text:0053C51C                 mov     eax, [ebp+var_8]
    .text:0053C51F                 mov     edx, [ebp+var_4]
    So in this case, it might be safe to say that somewhere, we've already see our target function!

    Now lets return back to the 1st function, and lets look at this code:

    Code:
    .text:004AFE11                 call    sub_53C500
    .text:004AFE16                 add     esp, 10h
    .text:004AFE19                 mov     [ebp+var_10], eax
    .text:004AFE1C                 mov     [ebp+var_C], edx
    .text:004AFE1F                 call    ClntObjMgrGetActivePlayer
    .text:004AFE24                 cmp     [ebp+var_10], eax
    .text:004AFE27                 jnz     short loc_4AFE2E
    .text:004AFE29                 cmp     [ebp+var_C], edx
    .text:004AFE2C                 jz      short loc_4AFE4E
    Since I have it labeled here, it's easy to see our target function, what else gives it away is that the logic here is comparing the return value of this function with the return value of sub_53C500! Which if they are equal, it will go to this branch:

    Code:
    .text:004AFE4E loc_4AFE4E:                             ; CODE XREF: sub_4AFDD0+5Cj
    .text:004AFE4E                                         ; sub_4AFDD0+6Cj
    .text:004AFE4E                 mov     ecx, [ebp+var_C]
    .text:004AFE51                 lea     edx, [ebp+var_8]
    .text:004AFE54                 push    edx
    .text:004AFE55                 mov     edx, [ebp+var_10]
    .text:004AFE58                 lea     eax, [ebp+var_4]
    .text:004AFE5B                 push    eax
    .text:004AFE5C                 push    ecx
    .text:004AFE5D                 push    edx
    .text:004AFE5E                 call    sub_4AEDC0
    .text:004AFE63                 add     esp, 10h
    Looking at sub_4AEDC0 we can see a string reference to WorldMap.cpp, it appears that The ID we retrieved earlier is passed to a different function that returns a pointer in EAX. Stay tuned for analysis of this function because this is the one that is useful!

    Memory Scanning: The Wrong Approach.
  2. #2
    Gothian's Avatar Member
    Reputation
    249
    Join Date
    Jul 2006
    Posts
    496
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quite informative to those who are well verse in ASM(?) I dont quite yet understand it all, but it looks very interesting. Here I am just looking for a method to find the current target pointer :P

    Soon you can find my projects at: www.termight.info

  3. #3
    schlumpf's Avatar Retired Noggit Developer

    Reputation
    755
    Join Date
    Nov 2006
    Posts
    2,759
    Thanks G/R
    0/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice contribution. You dont have to be that good in ASM to understand this. I never saw ASM before I first opened IDA. It just takes some time.

  4. #4
    kynox's Avatar Account not activated by Email
    Reputation
    830
    Join Date
    Dec 2006
    Posts
    888
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Without giving away too much information, 0x0046C240 is ClientObjMgrGetObjectByGuid.
    It takes 2 Parameters, the GUIDHigh and GUIDLow values, you can obtain the local players GUID from s_CurMgr at +0xC0.

    You can use the function at 0046A9A0 to obtain the local players GUID for you, however to call either of these functions you need to set your first TLS(Thread Local Storage) variable to the current s_curMgr ptr so that the functions can read them.

    Example of the calling procedure:

    Code:
    004066BF  |. E8 DC420600    CALL <WoW.GetActivePlayerGUID> ; 0046A9A0
    004066C4  |. 68 91000000    PUSH 91 ; Constant
    004066C9  |. 68 A0918600    PUSH AnyStringYouWish ; WoW uses the name of the source file calling it, i believe its just for debugging
    004066CE  |. 6A 10          PUSH 10 ; Constant
    004066D0  |. 52             PUSH EDX                                 ; GUIDLow
    004066D1  |. 50             PUSH EAX                                 ; GUIDHigh
    004066D2  |. E8 695B0600    CALL <WoW.GetObjectPtr> ; 0046C240
    Last edited by kynox; 12-09-2007 at 03:47 AM.

  5. #5
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1356
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice work. Another good way to get the pointers is through TLS, I believe Greyman has a thread up on WoWDev with some PoC code.

    Also, to anyone who wishes to use this information in a bot, I have written myself a little bot that injects itself and hooks the LUA functions to catch events and execute lua code, be VERY CAREFUL as to how you do this because Warden is checking for this type of behaviour. I suggest using debug registers to set the breakpoints you need to pull off such a feature.

  6. #6
    kynox's Avatar Account not activated by Email
    Reputation
    830
    Join Date
    Dec 2006
    Posts
    888
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm actually developing a framework to make creating a bot a very easy and viable task for the inexperienced when it comes to reverse engineering as there are people out there who could code kickass navigation, but wouldn't be able to put it to good use

    Nice work. Another good way to get the pointers is through TLS, I believe Greyman has a thread up on WoWDev with some PoC code.

    Also, to anyone who wishes to use this information in a bot, I have written myself a little bot that injects itself and hooks the LUA functions to catch events and execute lua code, be VERY CAREFUL as to how you do this because Warden is checking for this type of behaviour. I suggest using debug registers to set the breakpoints you need to pull off such a feature.


    As of late warden seems to be scanning a lot more WoW engine functions i've found, including but not limited to SendChatMessage, Model editing functions (Never fear, the F8 in my M/E is to restore the data!) and Frame/GlueXML signature verification. However a lot of it is just signature checks in each module.

    If anyone wants to "hide" their module from warden you need to hook Module32First/Next and either spoof the base or remove it completely, and i'm 90% sure they aren't verifying the integrity of the API they call. Removing it from the PEB wouldn't be such a bad idea either.
    Attached Files Attached Files
    Last edited by kynox; 12-09-2007 at 04:00 AM.

  7. #7
    raindog's Avatar Active Member
    Reputation
    68
    Join Date
    Dec 2007
    Posts
    51
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    looks like some tight code there man.

  8. #8
    tttommeke's Avatar Banned
    Reputation
    1
    Join Date
    Jul 2007
    Posts
    613
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Good guide, I was starting to learn ASM etc because it was faster. This helped me alot.

    +ReP

  9. #9
    Gothian's Avatar Member
    Reputation
    249
    Join Date
    Jul 2006
    Posts
    496
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by kynox View Post
    I'm actually developing a framework to make creating a bot a very easy and viable task for the inexperienced when it comes to reverse engineering as there are people out there who could code kickass navigation, but wouldn't be able to put it to good use



    As of late warden seems to be scanning a lot more WoW engine functions i've found, including but not limited to SendChatMessage, Model editing functions (Never fear, the F8 in my M/E is to restore the data!) and Frame/GlueXML signature verification. However a lot of it is just signature checks in each module.

    If anyone wants to "hide" their module from warden you need to hook Module32First/Next and either spoof the base or remove it completely, and i'm 90% sure they aren't verifying the integrity of the API they call. Removing it from the PEB wouldn't be such a bad idea either.
    I wish I knew C++ *cry*

    Soon you can find my projects at: www.termight.info

  10. #10
    raindog's Avatar Active Member
    Reputation
    68
    Join Date
    Dec 2007
    Posts
    51
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    C++ is just the beginning.

Similar Threads

  1. Blizzard is scanning the memory for Bot software names
    By meta23 in forum Diablo 3 General
    Replies: 30
    Last Post: 07-21-2012, 08:31 AM
  2. So you clicked the wrong Flight path
    By Nolixz in forum World of Warcraft Exploits
    Replies: 6
    Last Post: 11-25-2006, 10:56 PM
All times are GMT -5. The time now is 05:04 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search