reversing the return address check in 2.5.4.42940 menu

User Tag List

Results 1 to 2 of 2
  1. #1
    thateuler's Avatar Active Member
    Reputation
    30
    Join Date
    May 2019
    Posts
    44
    Thanks G/R
    25/21
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    reversing the return address check in 2.5.4.42940

    here's a cleanish c implementation that is easier to understand.

    the return address check starts at 0x1422BAE10 (base 0x140000000)


    Code:
    /*
      - TBC 2.5.4.42940
      - imagebase is 0x140000000
      - returns:
        1:  if the arg is a valid return address
        0:  if not
     */
    
    int
    check_retaddr(uint8_t *ret)
    {
            uint8_t *mem = 0;
    
            /* check 1. return address is inside .text */
            if (ret < (uint8_t*)0x14001000 || ret > (uint8_t*)0x142400B75)
                    return 0;
    
            /* check 2. invoked from a call.  rop check? */
            /* patterns: 0xe8, 0xff 0x1x, 0xff 0x5x, 0xff 0x9x, 0xff 0xdx */
            int iscall = 0; 
            uint64_t reti = (uint64_t)ret;
    
            if (mem[reti-5] == 0xe8) // call off4
                    iscall = 1;
            if (mem[reti-6] == 0xff && (((mem[reti-5] & 0x38) - 16 ) & 0xf7) == 0) // call [reg + off4]
                    iscall = 1;
            if (mem[reti-3] == 0xff && (((mem[reti-2] & 0x38) - 16 ) & 0xf7) == 0) // call [reg + off1]
                    iscall = 1;
            if (mem[reti-2] == 0xff && (((mem[reti-1] & 0x38) - 16 ) & 0xf7) == 0) // call reg, call [reg]
                    iscall = 1;
    
            if (! iscall)
                    return 0;
    
    
            /* check 3. the return address is on the good list */
    
            /* step 1. get the array of good return addresses */
            uint32_t *rettab = (void*)0x01400BBC84;
            uint64_t ret_offset = (uint64_t)ret - 0x140000000;
            uint32_t array_offset = rettab[ret_offset / 0x4000];
            if (array_offset == 0)
                    return 0;
    
            /* step 2. traverse the array. check if this address is listed */
            uint32_t *pgoodaddr = (uint32_t *)&rettab[array_offset/4];
            while (*pgoodaddr > 0) { 
                    if ( (*pgoodaddr - ret_offset) <= 64)
                            return 1;
                    pgoodaddr++;
            }
    
            return 0;
    }

    reversing the return address check in 2.5.4.42940
  2. Thanks Sacred, gdfsxwy, barthen (3 members gave Thanks to thateuler for this useful post)
  3. #2
    doityourself's Avatar ★ Elder ★
    Reputation
    1424
    Join Date
    Nov 2008
    Posts
    843
    Thanks G/R
    35/448
    Trade Feedback
    0 (0%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by thateuler View Post
    here's a cleanish c implementation that is easier to understand.

    the return address check starts at 0x1422BAE10 (base 0x140000000)


    Code:
    /*
      - TBC 2.5.4.42940
      - imagebase is 0x140000000
      - returns:
        1:  if the arg is a valid return address
        0:  if not
     */
    
    int
    check_retaddr(uint8_t *ret)
    {
            uint8_t *mem = 0;
    
            /* check 1. return address is inside .text */
            if (ret < (uint8_t*)0x14001000 || ret > (uint8_t*)0x142400B75)
                    return 0;
    
            /* check 2. invoked from a call.  rop check? */
            /* patterns: 0xe8, 0xff 0x1x, 0xff 0x5x, 0xff 0x9x, 0xff 0xdx */
            int iscall = 0; 
            uint64_t reti = (uint64_t)ret;
    
            if (mem[reti-5] == 0xe8) // call off4
                    iscall = 1;
            if (mem[reti-6] == 0xff && (((mem[reti-5] & 0x38) - 16 ) & 0xf7) == 0) // call [reg + off4]
                    iscall = 1;
            if (mem[reti-3] == 0xff && (((mem[reti-2] & 0x38) - 16 ) & 0xf7) == 0) // call [reg + off1]
                    iscall = 1;
            if (mem[reti-2] == 0xff && (((mem[reti-1] & 0x38) - 16 ) & 0xf7) == 0) // call reg, call [reg]
                    iscall = 1;
    
            if (! iscall)
                    return 0;
    
    
            /* check 3. the return address is on the good list */
    
            /* step 1. get the array of good return addresses */
            uint32_t *rettab = (void*)0x01400BBC84;
            uint64_t ret_offset = (uint64_t)ret - 0x140000000;
            uint32_t array_offset = rettab[ret_offset / 0x4000];
            if (array_offset == 0)
                    return 0;
    
            /* step 2. traverse the array. check if this address is listed */
            uint32_t *pgoodaddr = (uint32_t *)&rettab[array_offset/4];
            while (*pgoodaddr > 0) { 
                    if ( (*pgoodaddr - ret_offset) <= 64)
                            return 1;
                    pgoodaddr++;
            }
    
            return 0;
    }
    Additional little comment: You will see multiple versions and functions of the return address checks in the binary. Sometimes inlined, sometimes not. Sometimes without the check in the array and sometimes without.

Similar Threads

  1. [Live] About the integrity check in live
    By youyanruyu in forum WoW Memory Editing
    Replies: 10
    Last Post: 11-09-2021, 03:30 PM
  2. Replies: 12
    Last Post: 06-29-2021, 10:13 AM
  3. [Selling] Selling my account in the future. (price-check plz)
    By Manimal in forum WoW-US Account Buy Sell Trade
    Replies: 1
    Last Post: 05-14-2013, 12:19 PM
  4. [Selling] WoW Gold on EU Servers! Check in the cheap prices! [Private Seller]
    By Mammuten in forum World of Warcraft Buy Sell Trade
    Replies: 3
    Last Post: 12-30-2012, 07:40 AM
  5. Reversing the DB2 struct in memory
    By JuJuBoSc in forum WoW Memory Editing
    Replies: 4
    Last Post: 07-29-2012, 11:41 AM
All times are GMT -5. The time now is 08:31 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search