WoW Offsets learning menu

Shout-Out

User Tag List

Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 45
  1. #16
    Sweann's Avatar Active Member Authenticator enabled
    Reputation
    15
    Join Date
    Mar 2010
    Posts
    22
    Thanks G/R
    5/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by scizzydo View Post
    CGGameObject_C::GetLockRec:
    Code:
    40 53 48 83 EC 20 48 83 B9 ? ? ? ? 00 48 8B D9 74 ? 0F BE 89 ? ? 00 00
    Reverse it for what you want, or just call the function and get the rec to check the type.
    Thanks i will try my best to translate this to arm64, i didnt wrote that i am workin on OSX and so arm64

    WoW Offsets learning
  2. #17
    scizzydo's Avatar Contributor
    Reputation
    137
    Join Date
    Oct 2019
    Posts
    99
    Thanks G/R
    5/57
    Trade Feedback
    0 (0%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Sweann View Post
    Thanks i will try my best to translate this to arm64, i didnt wrote that i am workin on OSX and so arm64
    My apology. Also, it's macOS since Sierra in 2016, not OSX :P

    I don't have an arm mac, so my mac binary is also only x86. However, if you search the string "LOCKED_WITH_ITEM" you can find it used around there.
    Screenshot 2024-03-13 070559.png
    (In the image above it's the function that is highlighted)

  3. Thanks Sweann (1 members gave Thanks to scizzydo for this useful post)
  4. #18
    Sweann's Avatar Active Member Authenticator enabled
    Reputation
    15
    Join Date
    Mar 2010
    Posts
    22
    Thanks G/R
    5/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by scizzydo View Post
    My apology. Also, it's macOS since Sierra in 2016, not OSX :P

    I don't have an arm mac, so my mac binary is also only x86. However, if you search the string "LOCKED_WITH_ITEM" you can find it used around there.
    Screenshot 2024-03-13 070559.png
    (In the image above it's the function that is highlighted)
    True it's macOS and big thanks for the hint, looks like this is the same code

    Képernyőfotó 2024-03-13 - 16.49.37.png

  5. #19
    Sweann's Avatar Active Member Authenticator enabled
    Reputation
    15
    Join Date
    Mar 2010
    Posts
    22
    Thanks G/R
    5/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    And this function uses 0x148 offset what i already messing already it's look i was on good track:
    Code:
     if (*(long *)(param_1 + 0x148) == 0) {
        return 0;
      }
      uVar2 = FUN_1010909c4((long)*(char *)(param_1 + 0x24d),4);
      uVar3 = 0;
      if ((*(long *)(param_1 + 0x148) != 0) && (uVar2 < 0x23)) {
        iVar1 = *(int *)(*(long *)(param_1 + 0x148) + (ulong)uVar2 * 4 + 0x20);
        if (iVar1 == 0) {
          return 0;
        }
        uVar3 = FUN_10035f210(&DAT_102218bc0,iVar1,0,&uStack_21);
      }
      return uVar3;

  6. #20
    Sweann's Avatar Active Member Authenticator enabled
    Reputation
    15
    Join Date
    Mar 2010
    Posts
    22
    Thanks G/R
    5/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by scizzydo View Post
    I don't have an arm mac, so my mac binary is also only x86.
    Can i ask more info about your mac binary maybe next time if i stuck can start work on x64 binary.

  7. #21
    Sweann's Avatar Active Member Authenticator enabled
    Reputation
    15
    Join Date
    Mar 2010
    Posts
    22
    Thanks G/R
    5/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This code is to find property index for 4th parameter which is lock.

    Code:
    int GetPropNum(int object_type,int param_2)
    {
      int iVar1;
      
      if ((object_type < 0x3b) && (param_2 < 0x102)) {
        if (0 < *(int *)(&DAT_1027c9c28 + (long)object_type * 0x20)) {
          iVar1 = 0;
          do {
            if (*(int *)(*(long *)(&DAT_1027c9c30 + (long)object_type * 0x20) + (long)iVar1 * 4) ==
                param_2) {
              return iVar1;
            }
            iVar1 = iVar1 + 1;
          } while (*(int *)(&DAT_1027c9c28 + (long)object_type * 0x20) != iVar1);
        }
      }
      return -1;
    }
    Only issue was the "+ (long)iVar1 * 4" part because there i had to add 8, maybe Ghidra wasn't using proper width information.

    Calculating the offset looks the following: *( gameobject_ptr + 0x148 ) + 0x20 (0x20 because return (value * 4) + 0x20, but here i got 0) and this will point to a number which is correct.
    With "Copper Vein" is observed 19 and looked up here Wago Tools to ID and _index_0 will contain 3, this is the lock type need another check Wago Tools which gives us "Mine". Tried with a herb too and was okay.

  8. #22
    Archos's Avatar Member Authenticator enabled
    Reputation
    2
    Join Date
    Mar 2007
    Posts
    34
    Thanks G/R
    4/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What are you using to get a deobfuscated binary? Injecting a dylib that hooks the destructor? I am having issues getting a valid binary that I can open in Hopper.

  9. #23
    Archos's Avatar Member Authenticator enabled
    Reputation
    2
    Join Date
    Mar 2007
    Posts
    34
    Thanks G/R
    4/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The macOS release of WoW ships with a universal binary (FAT archive) that includes both ARM64 and X86_64 binaries. Obviously you cannot dump the ARM version from memory since you do not have an that processor, but you can statically browse it. Though if you DID have an Apple Silicon Mac you can actually run either binary (Though running as x86 using Rosetta is not very performant) which is handy.

  10. #24
    scizzydo's Avatar Contributor
    Reputation
    137
    Join Date
    Oct 2019
    Posts
    99
    Thanks G/R
    5/57
    Trade Feedback
    0 (0%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Archos View Post
    What are you using to get a deobfuscated binary? Injecting a dylib that hooks the destructor? I am having issues getting a valid binary that I can open in Hopper.
    Wrote this a while back:
    macOS x86_64 executable dylib dumper . GitHub

    And then just DYLD_INSERT_LIBRARIES the dylib on launch, then close the wow. I'm working something now to decrypt the arm one though from the x86_64 side

    Only arm Mac in my house is my wife's. I'll need to see if she lets me install wow on it to make the one for arm there. If you want, just adapt the xxx_64 structs.

    I'm working on just hooking Metal right now to do an overlay like the Vulkan and directx ones that exist, but am studying up on Metal more, as I haven't seen anything for what I want to do.
    Last edited by scizzydo; 03-15-2024 at 04:33 PM.

  11. #25
    Archos's Avatar Member Authenticator enabled
    Reputation
    2
    Join Date
    Mar 2007
    Posts
    34
    Thanks G/R
    4/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by scizzydo View Post
    Wrote this a while back:
    macOS x86_64 executable dylib dumper . GitHub

    And then just DYLD_INSERT_LIBRARIES the dylib on launch, then close the wow. I'm working something now to decrypt the arm one though from the x86_64 side
    Hey, thanks! I saw your post and modified it for for ARM64 but the binary I get back is not offset correctly since the ARM64 portion of the binary is located after the x86. Though, your script. does work if I execute it from `arch -x86_64 zsh`

    I was curious to know what Sweann was doing to get a good binary to extract. I have UTM downloading the IPSW I need to run a mac OS VM for further testing.

  12. #26
    scizzydo's Avatar Contributor
    Reputation
    137
    Join Date
    Oct 2019
    Posts
    99
    Thanks G/R
    5/57
    Trade Feedback
    0 (0%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Archos View Post
    Hey, thanks! I saw your post and modified it for for ARM64 but the binary I get back is not offset correctly since the ARM64 portion of the binary is located after the x86. Though, your script. does work if I execute it from `arch -x86_64 zsh`

    I was curious to know what Sweann was doing to get a good binary to extract. I have UTM downloading the IPSW I need to run a mac OS VM for further testing.
    I wonder if you handle the relocations and rebase them like in this guides Mach-O loader: Building a Custom Mach-O Memory Loader for macOS - Part 1 - XPN InfoSec Blog

    I'm tempted to get an arm Mac just to learn this stuff more than just guessing 😂 however, if I can just find the unpacker parts like I have on x86_64 you can unpack it from any architecture.

  13. #27
    Archos's Avatar Member Authenticator enabled
    Reputation
    2
    Join Date
    Mar 2007
    Posts
    34
    Thanks G/R
    4/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Screenshot 2024-03-15 at 4.57.40 PM.png
    Was able to get Frida connected in a VM! This should be easy

  14. #28
    Archos's Avatar Member Authenticator enabled
    Reputation
    2
    Join Date
    Mar 2007
    Posts
    34
    Thanks G/R
    4/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by scizzydo View Post
    I wonder if you handle the relocations and rebase them like in this guides Mach-O loader: Building a Custom Mach-O Memory Loader for macOS - Part 1 - XPN InfoSec Blog

    I'm tempted to get an arm Mac just to learn this stuff more than just guessing 😂 however, if I can just find the unpacker parts like I have on x86_64 you can unpack it from any architecture.
    Here is how far I have gotten.

    Code:
    //
    //  DumpBinary.c
    //  DumpBinary
    //  Look for Object manager list status
    //  Created by Alexandre Colucci on 04.08.2016.
    //  Copyright © 2016 Alexandre Colucci. All rights reserved.
    //
    //    To compile:
    //        gcc -o DumpBinary.dylib -dynamiclib DumpBinary.c
    //
    //    To run:
    //        DYLD_INSERT_LIBRARIES=./DumpBinary.dylib /Applications/World\ of\ Warcraft/_retail_/World\ of\ Warcraft.app/Contents/MacOS/World\ of\ Warcraft
    //
    
    
    #include  <stdio.h>
    #include  <stdlib.h>
    #include  <string.h>
    
    
    #include  <mach-o/loader.h>
    #include  <mach-o/dyld.h>
    #include  <mach-o/fat.h>
    #include  <mach-o/swap.h>
    
    
    // For PATH_MAX
    #include  <sys/syslimits.h>
    
    
    const struct mach_header_64 *get_mach_header_64()
    {
        for (uint32_t i = 0; i < _dyld_image_count(); ++i)
        {
            const struct mach_header_64 *mach_header_64 = (const struct mach_header_64 *)_dyld_get_image_header(i);
            if (mach_header_64->filetype == MH_EXECUTE)
            {
                if ((mach_header_64->cputype & CPU_TYPE_ARM64) != CPU_TYPE_ARM64)
                {
                    fprintf(stderr, "[ERROR] Executable is not an ARM64 file\n");
                    exit(1);
                }
                fprintf(stderr, "[INFO] Found MH_EXECUTE Header\n");
                const char *name = _dyld_get_image_name(i);
                fprintf(stderr, "[INFO] Executable is %s\n", "ARM64");
                fprintf(stdout, "[INFO] Executable header for '%s' found.\n", name);
                return mach_header_64;
            }
        }
        return NULL;
    }
    
    
    uint8_t *get_file_from_disk(const char *path, size_t *start, size_t *size)
    {
        fprintf(stdout, "[INFO] Loading '%s' from disk.\n", path);
    
    
        FILE *file = fopen(path, "r");
        if (file == NULL)
        {
            fprintf(stderr, "[ERROR] Could not open executable path '%s'\n", path);
            exit(1);
        }
    
    
        fseek(file, 0, SEEK_END);
        long file_size = ftell(file);
        fseek(file, 0, SEEK_SET);
        *size = file_size;
    
    
        uint8_t *buffer = (uint8_t *)calloc(file_size, 1);
        if (buffer == NULL)
        {
            fclose(file);
            fprintf(stderr, "[ERROR] Could not allocate buffer\n");
            exit(1);
        }
    
    
        if (fread(buffer, 1, file_size, file) != file_size)
        {
            fclose(file);
            free(buffer);
            fprintf(stderr, "[ERROR] Could not read the file '%s' to buffer\n", path);
            exit(1);
        }
        fclose(file);
    
    
        struct fat_header *fat_header = (struct fat_header *)buffer;
        if (fat_header->magic == FAT_CIGAM || fat_header->magic == FAT_MAGIC || fat_header->magic == FAT_CIGAM_64 || fat_header->magic == FAT_MAGIC_64)
        {
            bool byteswap = fat_header->magic == FAT_CIGAM || fat_header->magic == FAT_CIGAM_64;
            if (byteswap)
    #pragma  clang diagnostic ignored "-Wdeprecated-declarations"
                swap_fat_header(fat_header, 0);
            struct fat_arch *fat_arch = (struct fat_arch *)(fat_header + 1);
            for (uint32_t i = 0; i < fat_header->nfat_arch; ++i)
            {
                if (byteswap)
                    swap_fat_arch(fat_arch, 1, 0);
    #pragma  clang diagnostic ignored "-Wdeprecated-declarations"
                bool is_arm64 = (fat_arch->cputype & CPU_TYPE_ARM64) == CPU_TYPE_ARM64;
                bool is_x86_64 = (fat_arch->cputype & CPU_TYPE_X86_64) == CPU_TYPE_X86_64;
                if (is_arm64)
                {
                    *size = fat_arch->size;
                    *start = fat_arch->offset;
                    break;
                }
                ++fat_arch;
            }
        }
    
    
        return buffer;
    }
    
    
    void __attribute__((destructor)) DumpBinaryDestructor()
    {
        char destinationPath[PATH_MAX];
        fprintf(stderr, "[INFO] Destructor CALLED\n");
        const struct mach_header_64 *mh64 = get_mach_header_64();
        if (mh64 == NULL)
        {
            fprintf(stderr, "[ERROR] Could not find the main executable\n");
            exit(1);
        }
    
    
        char executablePath[PATH_MAX];
    
    
        /*
        _NSGetExecutablePath() copies the path of the main executable into the
         buffer buf.  The bufsize parameter should initially be the size of the
         buffer.  This function returns 0 if the path was successfully copied, and
         * bufsize is left unchanged.  It returns -1 if the buffer is not large
         enough, and * bufsize is set to the size required.  Note that
         _NSGetExecutablePath() will return "a path" to the executable not a "real
         path" to the executable.  That is, the path may be a symbolic link and
         not the real file. With deep directories the total bufsize needed could
         be more than MAXPATHLEN.
        */
        uint32_t len = sizeof(executablePath);
        if (_NSGetExecutablePath(executablePath, &len) != 0)
        {
            fprintf(stderr, "[ERROR] Buffer is not large enough to copy the executable path\n");
            exit(1);
        }
    
    
        //
        // Get the canonicalized absolute path
        //
        char *canonicalPath = realpath(executablePath, NULL);
        if (canonicalPath != NULL)
        {
            strlcpy(executablePath, canonicalPath, sizeof(executablePath));
            free(canonicalPath);
        }
    
    
        fprintf(stderr, "[INFO] Found absolute path: '%s'\n", executablePath);
    
    
        size_t buffer_start = 0, buffer_size = 0;
        uint8_t *buffer = get_file_from_disk(executablePath, &buffer_start, &buffer_size);
    
    
        //
        // Loop through each section
        //
        size_t segmentOffset = sizeof(struct mach_header_64);
        fprintf(stderr, "[INFO] Commnd Size %d\n", mh64->sizeofcmds);
        for (uint32_t i = 0; i < mh64->ncmds; i++)
        {
            struct load_command *loadCommand = (struct load_command *)((uint8_t *)mh64 + segmentOffset);
            if (loadCommand->cmd == LC_SEGMENT_64)
            {
                // Found a 64-bit segment
                struct segment_command_64 *segCommand = (struct segment_command_64 *)loadCommand;
    
    
                void *sectionPtr = (void *)(segCommand + 1);
                for (uint32_t nsect = 0; nsect < segCommand->nsects; ++nsect)
                {
                    struct section_64 *section = (struct section_64 *)sectionPtr;
                    fprintf(stderr, "\t[INFO] Found the section (%s, %s)\n", section->segname, section->sectname);
                    if (strncmp(segCommand->segname, SEG_TEXT, 16) == 0)
                    {
                        fprintf(stderr, "\t[INFO] Save the unencrypted (%s, %s) section to the buffer\n", section->segname, section->sectname);
                        memcpy(buffer + section->offset, (uint8_t *)mh64 + section->offset, section->size);
                    }
    
    
                    sectionPtr += sizeof(struct section_64);
                }
            }
            segmentOffset += loadCommand->cmdsize;
        }
    start_dump:
        //
        // Create the output file
        //
        // char appendName[12] = mh64->cputype == CPU_TYPE_ARM64 ? "_Decrypted_a" : "_Decrypted_x";
        strlcpy(destinationPath, executablePath, sizeof(destinationPath));
        strlcat(destinationPath, mh64->cputype == CPU_TYPE_ARM64 ? "_Decrypted_a" : "_Decrypted_x", sizeof(destinationPath));
    
    
        fprintf(stderr, "[INFO] Creating the output file '%s'\n", destinationPath);
        FILE *destinationFile = fopen(destinationPath, "w");
    
    
        if (destinationFile == NULL)
        {
            free(buffer);
            fprintf(stderr, "[ERROR] Could create the output file '%s'\n", destinationPath);
            exit(1);
        }
    
    
        //
        // Save the data into the output file
        //
        if (fwrite(buffer + buffer_start, 1, buffer_size, destinationFile) != buffer_size)
        {
            free(buffer);
            fclose(destinationFile);
            fprintf(stderr, "[ERROR] Could not write to the output file\n");
            exit(1);
        }
    
    
        free(buffer);
        fclose(destinationFile);
        fprintf(stderr, "[INFO] Decryption completed\n");
    }

  15. #29
    Sweann's Avatar Active Member Authenticator enabled
    Reputation
    15
    Join Date
    Mar 2010
    Posts
    22
    Thanks G/R
    5/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Archos View Post
    What are you using to get a deobfuscated binary? Injecting a dylib that hooks the destructor? I am having issues getting a valid binary that I can open in Hopper.
    Simply reading the program memory the first entry and write it to disk, and fixing lazy load part so ghidra can load, maybe that segment holds some memory pointers during deobfuscation.

    Hopper was always ok to process the dumped binary so far, just ghidra needed a mach-o fix.
    Last edited by Sweann; 03-16-2024 at 04:28 PM.

  16. #30
    Sweann's Avatar Active Member Authenticator enabled
    Reputation
    15
    Join Date
    Mar 2010
    Posts
    22
    Thanks G/R
    5/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Archos View Post
    Hey, thanks! I saw your post and modified it for for ARM64 but the binary I get back is not offset correctly since the ARM64 portion of the binary is located after the x86. Though, your script. does work if I execute it from `arch -x86_64 zsh`

    I was curious to know what Sweann was doing to get a good binary to extract. I have UTM downloading the IPSW I need to run a mac OS VM for further testing.
    My binary is only good for static analysis never tried to run or hook anything i just using memory reading nothing more.

Page 2 of 3 FirstFirst 123 LastLast

Similar Threads

  1. [PQR] Custom wow offset?
    By cabrobas in forum WoW Memory Editing
    Replies: 2
    Last Post: 04-04-2022, 04:40 PM
  2. WoW Offsets & WPE
    By RyanoAthens in forum World of Warcraft General
    Replies: 2
    Last Post: 03-11-2014, 10:15 PM
  3. 4.0.3 Wow - Offsets
    By luciferc in forum WoW Memory Editing
    Replies: 51
    Last Post: 11-25-2010, 12:04 PM
  4. im going to use wow to learn french!
    By Ermok in forum World of Warcraft General
    Replies: 7
    Last Post: 09-10-2007, 04:02 PM
All times are GMT -5. The time now is 06:05 PM. 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