Results 1 to 5 of 5
  1. #1
    -:TKK:-WaSsUp's Avatar
    Join Date
    Sep 2010
    Gender
    male
    Posts
    27
    Reputation
    10
    Thanks
    14

    E.S.P. in Call of Duty 4

    *A lot of this tutorial revolves around you having a decent understanding of finding Call of Duty 4's native name-tags function.

    The basic concept behind this method is rather simple; we know how to draw name-tags through walls, for both our team and the opposite. Because of this, we know that Call of Duty 4 must have a function that converts the 3D coordinates of each of the players into 2D coordinates that the game can then use to print on the screen. This leaves us with one of two choices for creating an ESP: we can either locate the functions responsible for transforming the coordinates, or we can simply hook directly above the actual function responsible for printing the tags, and steal the coordinates. Either way works, but for time - and, I must confess - ease I have chosen the latter.

    From the previous tutorial, the following call is responsible for printing the name-tags:
    Code:
    Code:
    0042F6C9  |. E8 A2FEFFFF       CALL iw3mp.0042F570
    Which contains a function that looks like:
    Code:
    Code:
    0042F570  /$ 51                PUSH ECX
    0042F571  |. 56                PUSH ESI
    0042F572  |. E8 29EDFFFF       CALL iw3mp.0042E2A0
    0042F577  |. 83C4 04           ADD ESP,4
    0042F57A  |. 56                PUSH ESI
    0042F57B  |. E8 50EBFFFF       CALL iw3mp.0042E0D0
    0042F580  |. 83C4 04           ADD ESP,4
    0042F583  |. 59                POP ECX
    0042F584  \. C3                RETN
    And, also, from before, we know that the second function call contains a nice loop which we can only assume is responsible for building the name-tags amoung all the entities. It only makes sense that best place to look is at the bottom of this loop, as the perfect place to finally draw the names is once everything else is taken care of. Scrolling down, the last call in this loop is:
    Code:
    Code:
    0042E257  |> 51                |PUSH ECX
    0042E258  |. D95C24 1C         |FSTP DWORD PTR SS:[ESP+1C]
    0042E25C  |. D94424 1C         |FLD DWORD PTR SS:[ESP+1C]
    0042E260  |. 8B4C24 30         |MOV ECX,DWORD PTR SS:[ESP+30]
    0042E264  |. D91C24            |FSTP DWORD PTR SS:[ESP]
    0042E267  |. 56                |PUSH ESI
    0042E268  |. 51                |PUSH ECX
    0042E269  |. E8 02F5FFFF       |CALL iw3mp.0042D770
    But just for grins, it should make sense that this is called in the former of the two functions from before, so navigate back, and upon entering it and scrolling down, we see our guess is correct:
    Code:
    Code:
    0042E3CC   . 51                PUSH ECX
    0042E3CD   . 8B4C24 18         MOV ECX,DWORD PTR SS:[ESP+18]
    0042E3D1   . D91C24            FSTP DWORD PTR SS:[ESP]
    0042E3D4   . 56                PUSH ESI
    0042E3D5   . 51                PUSH ECX
    0042E3D6   . E8 95F3FFFF       CALL iw3mp.0042D770
    Enter the call to 42D770h so we can begin to piece this out - scrolling down, this gem should immediately catch your eye:
    Code:
    Code:
    0042D845  |. 50                PUSH EAX                                  ; /Arg3
    0042D846  |. 68 607D6C00       PUSH iw3mp.006C7D60                       ; |Arg2 = 006C7D60 ASCII \"Unable to get name for client num: %i
    \"
    0042D84B  |. 6A 0E             PUSH 0E                                   ; |Arg1 = 0000000E
    0042D84D  |. E8 2EF40C00       CALL iw3mp.004FCC80                       ; \iw3mp.004FCC80
    Well, we are definitely in some function responsible for printing client names, look around the function and you should stumble upon a call that looks like:
    Code:
    Code:
    0042D9FE  |. 6A 00             PUSH 0
    0042DA00  |. 6A 00             PUSH 0
    0042DA02  |. 6A 00             PUSH 0
    0042DA04  |. 6A 00             PUSH 0
    0042DA06  |. D95C24 54         FSTP DWORD PTR SS:[ESP+54]
    0042DA0A  |. D94424 28         FLD DWORD PTR SS:[ESP+28]
    0042DA0E  |. 6A 00             PUSH 0
    0042DA10  |. 6A 00             PUSH 0
    0042DA12  |. 8BCF              MOV ECX,EDI
    0042DA14  |. 51                PUSH ECX                                  ;  colour
    0042DA15  |. 6A 03             PUSH 3
    0042DA17  |. 8D5424 68         LEA EDX,DWORD PTR SS:[ESP+68]
    0042DA1B  |. 52                PUSH EDX
    0042DA1C  |. 83EC 10           SUB ESP,10
    0042DA1F  |. D95424 0C         FST DWORD PTR SS:[ESP+C]
    0042DA23  |. 8D8424 8C000000   LEA EAX,DWORD PTR SS:[ESP+8C]
    0042DA2A  |. D95C24 08         FSTP DWORD PTR SS:[ESP+8]                 ;  scale
    0042DA2E  |. D94424 54         FLD DWORD PTR SS:[ESP+54]
    0042DA32  |. D95C24 04         FSTP DWORD PTR SS:[ESP+4]                 ;  y
    0042DA36  |. D94424 48         FLD DWORD PTR SS:[ESP+48]
    0042DA3A  |. D91C24            FSTP DWORD PTR SS:[ESP]                   ;  x
    0042DA3D  |. 53                PUSH EBX                                  ;  font
    0042DA3E  |. 6A 20             PUSH 20
    0042DA40  |. 50                PUSH EAX                                  ;  text
    0042DA41  |. E8 7A2C0400       CALL iw3mp.004706C0                       ;  print names
    From our work with drawing static text (DoxCoding Forums View topic - Drawing Text Using Engine Functions[CoD4][mAsm]), we know that Call of Duty 4's text functions seem to like to transfer x, y, and the scale in esp, esp + 4, and esp + 8, respectively. So just to ensure that we are correct, let us place a breakpoint on the "sub esp, 10h" at 42DA1Ch, and step through this. Run into view of a name-tag, and you should see that as Call of Duty 4 adjusts for distance, esp + 8 varies between 0.4 and 0.8, and that esp + 4 and esp hold values that certainly could be x, and y. The rest of the parametres pushed are documented, and can be found and understood by simply stepping through the series of pushes.

    It bares mentioning here two facts - the first being that this is not an actual text-out function; enter the call, and you will see this is simply a wrapper for another text-out function:
    Code:
    Code:
    004706C0  /$ 8B4424 40         MOV EAX,DWORD PTR SS:[ESP+40]
    004706C4  |. D9EE              FLDZ
    004706C6  |. 8B4C24 3C         MOV ECX,DWORD PTR SS:[ESP+3C]
    004706CA  |. 8B5424 38         MOV EDX,DWORD PTR SS:[ESP+38]
    004706CE  |. 50                PUSH EAX
    004706CF  |. 8B4424 38         MOV EAX,DWORD PTR SS:[ESP+38]
    004706D3  |. 51                PUSH ECX
    004706D4  |. 8B4C24 38         MOV ECX,DWORD PTR SS:[ESP+38]
    004706D8  |. 52                PUSH EDX
    004706D9  |. 8B5424 38         MOV EDX,DWORD PTR SS:[ESP+38]
    004706DD  |. 50                PUSH EAX
    004706DE  |. 8B4424 38         MOV EAX,DWORD PTR SS:[ESP+38]
    004706E2  |. 51                PUSH ECX
    004706E3  |. 8B4C24 38         MOV ECX,DWORD PTR SS:[ESP+38]
    004706E7  |. 52                PUSH EDX
    004706E8  |. 8B5424 38         MOV EDX,DWORD PTR SS:[ESP+38]
    004706EC  |. 50                PUSH EAX
    004706ED  |. 8B4424 28         MOV EAX,DWORD PTR SS:[ESP+28]
    004706F1  |. 51                PUSH ECX
    004706F2  |. 8B4C24 28         MOV ECX,DWORD PTR SS:[ESP+28]
    004706F6  |. 52                PUSH EDX
    004706F7  |. 8B5424 28         MOV EDX,DWORD PTR SS:[ESP+28]
    004706FB  |. 83EC 14           SUB ESP,14
    004706FE  |. D95C24 10         FSTP DWORD PTR SS:[ESP+10]
    00470702  |. D94424 54         FLD DWORD PTR SS:[ESP+54]
    00470706  |. D95C24 0C         FSTP DWORD PTR SS:[ESP+C]
    0047070A  |. D94424 50         FLD DWORD PTR SS:[ESP+50]
    0047070E  |. D95C24 08         FSTP DWORD PTR SS:[ESP+8]
    00470712  |. D94424 4C         FLD DWORD PTR SS:[ESP+4C]
    00470716  |. D95C24 04         FSTP DWORD PTR SS:[ESP+4]
    0047071A  |. D94424 48         FLD DWORD PTR SS:[ESP+48]
    0047071E  |. D91C24            FSTP DWORD PTR SS:[ESP]
    00470721  |. 50                PUSH EAX
    00470722  |. 51                PUSH ECX
    00470723  |. 52                PUSH EDX
    00470724  |. E8 07661800       CALL iw3mp.005F6D30
    00470729  |. 83C4 44           ADD ESP,44
    0047072C  \. C3                RETN
    The second is that Call of Duty 4 uses several text-out functions, and each display text differently. The text-out function I had found before, and used both in my tutorial, and the coffee series of releases, takes a maximum x and y of around 600. This is important when you realise that this function takes a maximum x and y of around 2000; bottom line, the two functions are not interchangeable.

    But, with all that, we can now move onto coding this.

    *Some of the base stuff I literally copied and pasted from my previous tutorials since the same ideas apply. This is my apology for being a lazy bum.*

    So here I'm probably going to lose a lot of you, because we are going to be coding this in assembly. I'll give you the chance to hit the back button on your browser...

    ...for those of you still around, let's start.

    * I personally use RadASM, and although I would strongly suggest it, you are free to write the code in whatever you want. I'm using MASM to assemble and link though, so it is likely that some of the code will not work on other ASM packages, although, it shouldn't be too hard to edit. *

    First, let's get the shell set up (this is a .DLL for any that didn't guess):
    Code:
    Code:
    .386
    .model flat, stdcall
    option casemap: none
    
    .code
        _main:
    
        end _main
    Now, before the code section, but under the option, we need to throw in some includes:
    Code:
    Code:
    include \masm32\macros\macros.asm
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\kernel32.lib
    ow we need some data to dump all the data we found during our struggles - create a .data section under your includes, but above the .code section, and put:
    Code:
    Code:
    .data
        staticY real4 100.0f
        jmpback_draw_tags dd 42da40h
        @ori_text_out dd 4706c0h
        hold dd 0
    Okay, now on to the actual .DLL, in main:
    Code:
    Code:
    push ebp
            mov ebp, esp
            mov eax, dword ptr ds:[ ebp + 0ch ]
            cmp eax,1
            jnz @NOT_DLL_ATTACH
            push eax
            ;our code will go here
            pop eax
            @NOT_DLL_ATTACH:
            
                leave
                retn 0ch
    * I did give you the chance to leave. If you're going to code in assembly, you better be prepared to write in assembly, not this semi-H.L.A. shit mASM now supports. *

    Okay, basic rundown of this code; since this is a .DLL, one of our main concerns is about keeping everything nice and balanced. First we push the base pointer on the stack, the move the stack pointer into the base pointer,which basically tells the running code that the current base of the program is the base of our .DLL, which Mr. Computer needs to know so he (there are no girls on the internet, therefore, computers are always guys) can figure out where to return upon calls, jumps, calculations, etc. The push saves the base pointer on the stack, so that when we leave our function and return, the base is set again to CoD4's base pointer. After that we move the data in the base pointer + Ch (12d), which holds the reason for our .DLL being called.

    * ebp = base
    ebp + 4 = __stdcall DllMain
    ebp + 8 = hModule
    ebp + 12 = ul_reason_for_call
    ebp + 16 = lpReserved *

    If the reason is DLL_PROCESS_ATTACH (or 1h), then we want to execute our code, otherwise, we want to leave our .DLL and return execution flow to CoD4's (making sure to balance the stack - three parametres = retn CH).

    * eax needs to hold the reason for the call at the return of our .DLL, so we preserve it by push'ing it before our function calls, and pop'ing it right before we return. *

    * I apologise in advance for using invoke, the code was getting a tad unruly. *

    With our base set up, we know that we are going to need to modify some memory for our hook, so we should allocate some place for the old protection type:
    Code:
    Code:
    invoke VirtualAlloc, 0, 4, 1000h, 40h
            mov ebx, eax
    First, let's remove the limitations on seeing enemy name-tags, as well as seeing name-tags through walls - both discussed in the tutorial at the beginning of this article:
    Code:
    Code:
    invoke VirtualProtect, 42dea4h, 6, 40h, ebx    
            mov byte ptr ds:[ 42dea4h ], 0e9h
            mov dword ptr ds:[ 42dea5h ], 0000020ah
            mov byte ptr ds:[ 42dea9h ], 90h
            invoke VirtualProtect, 42dea4h, 6, dword ptr ds:[ ebx ], ebx
            
            invoke VirtualProtect, 42e1ach, 6, 40h, ebx
            xor ecx,ecx
            @@:
            
                mov byte ptr ds:[ 42e1ach + ecx ], 90h
                inc ecx
                cmp ecx, 6
                jl @b
            
            invoke VirtualProtect, 42e1ach, 6, dword ptr ds:[ ebx ], ebx
    Next, we are going to hook the text-out function right above the actual call - at 42DA3Ah to be exact:
    Code:
    Code:
    invoke VirtualProtect, 42da3ah, 6, 40h, ebx                ;unprotect the memory
            mov byte ptr ds:[ 42da3ah ], 0e9h                ;create a patch, e9h being a jump
            lea ecx, @draw_ESP                    ;move the address of our function into ecx
            sub ecx, 42da3fh                    ;subtract the caller + 5 from callee 
            mov dword ptr ds:[ 42da3bh ], ecx                ;move the result into 42da3ah + 1
            mov byte ptr ds:[ 42da3fh ], 90h                ;nop out the final byte to balance out the six bytes
            invoke VirtualProtect, 42da3ah, 6, dword ptr ds:[ ebx ], ebx        ;reprotect the memory
    Getting close, but before we can right our ESP function, we have to copy over the draw_text function over from CoD4; under the retn 0ch:
    Code:
    Code:
    ; edx = x
            ; ebx = y
            ; ecx = text
            @draw_text:
            
                push 0
                push 0
                push 0
                push 0
                push 0
                push 0
                push 0    
                push 3
                push 0
                fld1
                sub esp, 10h
                fst dword ptr ss:[ esp + 0ch ]
                fstp dword ptr ss:[ esp + 8 ]
                fld dword ptr ds:[ ebx ]
                fstp dword ptr ss:[ esp + 4 ]
                fld dword ptr ds:[ edx ]
                fstp dword ptr ss:[ esp ]
                push 0f8d6ech
                push 20
                push ecx
                call dword ptr cs:[ @ori_text_out ]
                add esp, 40h
                retn

    I realise I left out the colour, but this is primarily due to laziness; besides, it is not to hard to implement this yourself.

    Time to move onto the draw_ESP function:
    Code:
    Code:
    @draw_ESP:
    To make the math easy as possible, I tried to maintain the stack as much as possible from the jump to my own call - essentially, I ordered the reconstruction of the code I removed so that it was possible to only account for my modifications:
    Code:
    fstp dword ptr ss:[ esp ]
                
                mov hold, eax
                ;code to go here
                mov eax, hold
                        
                push ebx
                push 20h    
                jmp jmpback_draw_tags
    * The reason for the hold is that I was experiencing some problems with the initial name in eax (probably as a result of the call to my own text-out function) being over-written. *

    Next to save edx, ebx, and ecx:
    Code:
    Code:
    push edx
                push ebx
                push ecx
                ;and here
                pop ecx
                pop ebx
                pop edx
    All that is left now is a call to our function:
    Code:
    Code:
    fld dword ptr ss:[ esp + 0ch ]                ;+0ch to account for the three pushes
                fstp dword ptr ds:[ edx ]
                lea ebx, staticY
                lea ecx, CTXT( \"X\" )
                call @draw_text
    The final code for easy C+P:
    Code:
    Code:
    .386
    .model flat, stdcall
    option casemap: none
    
    include \masm32\macros\macros.asm
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\kernel32.lib
        
    .data
    
        staticY real4 100.0f
        jmpback_draw_tags dd 42da40h
        @ori_text_out dd 4706c0h
        hold dd 0
    
    .code
    
        _main:
        
            push ebp
            mov ebp, esp
            mov eax, dword ptr ds:[ ebp + 0ch ]
            cmp eax,1
            jnz @NOT_DLL_ATTACH
            push eax
            invoke VirtualAlloc, 0, 4, 1000h, 40h
            mov ebx, eax
            
            invoke VirtualProtect, 42da3ah, 6, 40h, ebx
            mov byte ptr ds:[ 42da3ah ], 0e9h
            lea ecx, @draw_ESP
            sub ecx, 42da3fh
            mov dword ptr ds:[ 42da3bh ], ecx
            mov byte ptr ds:[ 42da3fh ], 90h
            invoke VirtualProtect, 42da3ah, 6, dword ptr ds:[ ebx ], ebx
           
            invoke VirtualProtect, 42dea4h, 6, 40h, ebx    
            mov byte ptr ds:[ 42dea4h ], 0e9h
            mov dword ptr ds:[ 42dea5h ], 0000020ah
            mov byte ptr ds:[ 42dea9h ], 90h
            invoke VirtualProtect, 42dea4h, 6, dword ptr ds:[ ebx ], ebx
            
            invoke VirtualProtect, 42e1ach, 6, 40h, ebx
            xor ecx,ecx
            @@:
            
                mov byte ptr ds:[ 42e1ach + ecx ], 90h
                inc ecx
                cmp ecx, 6
                jl @b
            
            invoke VirtualProtect, 42e1ach, 6, dword ptr ds:[ ebx ], ebx
            
            invoke VirtualFree, ebx, 4, 4000h
            pop eax
            @NOT_DLL_ATTACH:
            
                leave
                retn 0ch
            
            ; edx = x
            ; ebx = y
            ; ecx = text
            @draw_text:
            
                push 0
                push 0
                push 0
                push 0
                push 0
                push 0
                push 0    
                push 3
                push 0
                fld1        ;push 1.00 on the stack
                sub esp, 10h
                fst dword ptr ss:[ esp + 0ch ]
                fstp dword ptr ss:[ esp + 8 ]
                fld dword ptr ds:[ ebx ]
                fstp dword ptr ss:[ esp + 4 ]
                fld dword ptr ds:[ edx ]
                fstp dword ptr ss:[ esp ]
                push 0f8d6ech
                push 20
                push ecx
                call dword ptr cs:[ @ori_text_out ]
                add esp, 40h
                retn
                
            @draw_ESP:
                
                fstp dword ptr ss:[ esp ]
                
                mov hold, eax
                push edx
                push ebx
                push ecx
                fld dword ptr ss:[ esp + 0ch ]
                fstp dword ptr ds:[ edx ]
                lea ebx, staticY
                lea ecx, CTXT( \"X\" )
                call @draw_text
                pop ecx
                pop ebx
                pop edx
                mov eax, hold
                        
                push ebx
                push 20h    
                jmp jmpback_draw_tags
                
                
        end _main
    Obviously from this code, this will only print above the X location of the player, however, this is quite easy to change if you have a basic understanding of the code we reversed. This is also not being realised to its ability - for example, you can grab the colour off the stack, and distinguish between friend and enemy. To get a true sense of use though, it might be useful to reverse the function, and figure out which calls are responsible for transforming the 3D coordinate the function starts with and implement them in a more traditional`WorldToScreen' function; in this way it is possible to write a less limited ESP. But I will leave that up to you, until next time:
    Last edited by -:TKK:-WaSsUp; 10-21-2010 at 01:41 PM.

  2. The Following 2 Users Say Thank You to -:TKK:-WaSsUp For This Useful Post:

    unknown2009 (10-21-2010),zanny1 (10-21-2010)

  3. #2
    matjuh123's Avatar
    Join Date
    Feb 2010
    Gender
    male
    Location
    So.. you didn't look in your closet yet?
    Posts
    1,204
    Reputation
    21
    Thanks
    623
    My Mood
    Amazed
    Remove the outside link!
    -I'm back as an active member. (8th December, 2013)

  4. The Following User Says Thank You to matjuh123 For This Useful Post:

    helgjep (11-21-2010)

  5. #3
    zanny1's Avatar
    Join Date
    Nov 2009
    Gender
    male
    Location
    Penis man
    Posts
    341
    Reputation
    10
    Thanks
    82
    My Mood
    Amazed
    interesting shit
    Quote Originally Posted by AZUMIKKEL View Post
    Or how about an erotic gamemode for once. Where if there's a girl in the match you can choose to rape her - or else it'll just be gay porn. Then the people here on MPGH has something to do.

  6. #4
    unknown2009's Avatar
    Join Date
    Apr 2009
    Gender
    male
    Location
    Alpha Moon!
    Posts
    73
    Reputation
    10
    Thanks
    19
    My Mood
    Confused
    i swear god ill kiss your ass <3....
    this thing is perfect for the mw2 esp
    That's what i do when i get backstabbed

  7. #5
    xbeatsszzx's Avatar
    Join Date
    Feb 2010
    Gender
    male
    Location
    Behind a dumpster jerking off. xD jks
    Posts
    2,520
    Reputation
    13
    Thanks
    1,494
    My Mood
    Asleep
    wow nice gj
    I Am on this site for the mods for mw2 ONLY. Not hacks.

Similar Threads

  1. Call of Duty 2
    By 1877 in forum Hack Requests
    Replies: 1
    Last Post: 01-02-2010, 09:50 AM
  2. Call of duty 1.5 hack
    By olib in forum General Game Hacking
    Replies: 2
    Last Post: 02-27-2008, 09:42 AM
  3. Call of Duty Multiplayer
    By Andrea90 in forum General
    Replies: 1
    Last Post: 06-04-2007, 10:08 AM
  4. Call of duty: United offensive
    By triad in forum General Game Hacking
    Replies: 0
    Last Post: 12-17-2006, 09:25 AM
  5. Call Of Duty Hack Question----
    By -[standoff]- in forum General Game Hacking
    Replies: 6
    Last Post: 07-03-2006, 08:16 PM