Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Getting stack address

Getting stack address

Scheduled Pinned Locked Moved C / C++ / MFC
visual-studiodata-structuresquestion
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    Hans Dietrich
    wrote on last edited by
    #1

    I'm currently updating my XCrashReport article, and I had forgotten that I have some assembler in it:

    \_\_asm
    {
        // Load the top (highest address) of the stack from the
        // thread information block. 
        mov    eax, fs:\[4\]
        mov pStackTop, eax
    }
    

    The purpose of this is to get the top of the stack, so I can do a stack dump. Unfortunately, I need to replace it, since VS doesn't allow asm code when compiling for x64. I have found this code, which works ok in x86:

    NT\_TIB \*pTib = (NT\_TIB \*)NtCurrentTeb();
    PVOID pStackTop = pTib->StackBase;
    

    I am just wondering if this will work on x64 as well (haven't had a chance to try it yet). Anyone have any experience with this technique?

    Best wishes, Hans


    [Hans Dietrich Software]

    _ M 2 Replies Last reply
    0
    • H Hans Dietrich

      I'm currently updating my XCrashReport article, and I had forgotten that I have some assembler in it:

      \_\_asm
      {
          // Load the top (highest address) of the stack from the
          // thread information block. 
          mov    eax, fs:\[4\]
          mov pStackTop, eax
      }
      

      The purpose of this is to get the top of the stack, so I can do a stack dump. Unfortunately, I need to replace it, since VS doesn't allow asm code when compiling for x64. I have found this code, which works ok in x86:

      NT\_TIB \*pTib = (NT\_TIB \*)NtCurrentTeb();
      PVOID pStackTop = pTib->StackBase;
      

      I am just wondering if this will work on x64 as well (haven't had a chance to try it yet). Anyone have any experience with this technique?

      Best wishes, Hans


      [Hans Dietrich Software]

      _ Offline
      _ Offline
      _Superman_
      wrote on last edited by
      #2

      In x64, the FS register has been replaced by the GS register. And you have to use compiler intrinsics instead of inline assembly. The following intrinsics will allow you to read from an offset in the GS register.

      __readgsbyte
      __readgsword
      __readgsdword
      __readgsqword

      Just for completeness, there are also similar intrinsics available in x86 to read from an offset of the FS register -

      __readfsbyte
      __readfsword
      __readfsdword
      __readfsqword

      «_Superman_»
      I love work. It gives me something to do between weekends.

      Microsoft MVP (Visual C++)

      Polymorphism in C

      H 1 Reply Last reply
      0
      • _ _Superman_

        In x64, the FS register has been replaced by the GS register. And you have to use compiler intrinsics instead of inline assembly. The following intrinsics will allow you to read from an offset in the GS register.

        __readgsbyte
        __readgsword
        __readgsdword
        __readgsqword

        Just for completeness, there are also similar intrinsics available in x86 to read from an offset of the FS register -

        __readfsbyte
        __readfsword
        __readfsdword
        __readfsqword

        «_Superman_»
        I love work. It gives me something to do between weekends.

        Microsoft MVP (Visual C++)

        Polymorphism in C

        H Offline
        H Offline
        Hans Dietrich
        wrote on last edited by
        #3

        Thanks, that looks more straightforward. I got the stack top using

        void \*pStackTop = (void \*) \_\_readfsdword(0x04);
        

        so on x64 I would use

        void \*pStackTop = (void \*) \_\_readgsdword(0x04);
        

        Or would it be __readgsqword ?

        Best wishes, Hans


        [Hans Dietrich Software]

        _ 1 Reply Last reply
        0
        • H Hans Dietrich

          Thanks, that looks more straightforward. I got the stack top using

          void \*pStackTop = (void \*) \_\_readfsdword(0x04);
          

          so on x64 I would use

          void \*pStackTop = (void \*) \_\_readgsdword(0x04);
          

          Or would it be __readgsqword ?

          Best wishes, Hans


          [Hans Dietrich Software]

          _ Offline
          _ Offline
          _Superman_
          wrote on last edited by
          #4

          Since all pointers are 64-bit in x64, I guess you should be using __readgsqword.

          «_Superman_»
          I love work. It gives me something to do between weekends.

          Microsoft MVP (Visual C++)

          Polymorphism in C

          1 Reply Last reply
          0
          • H Hans Dietrich

            I'm currently updating my XCrashReport article, and I had forgotten that I have some assembler in it:

            \_\_asm
            {
                // Load the top (highest address) of the stack from the
                // thread information block. 
                mov    eax, fs:\[4\]
                mov pStackTop, eax
            }
            

            The purpose of this is to get the top of the stack, so I can do a stack dump. Unfortunately, I need to replace it, since VS doesn't allow asm code when compiling for x64. I have found this code, which works ok in x86:

            NT\_TIB \*pTib = (NT\_TIB \*)NtCurrentTeb();
            PVOID pStackTop = pTib->StackBase;
            

            I am just wondering if this will work on x64 as well (haven't had a chance to try it yet). Anyone have any experience with this technique?

            Best wishes, Hans


            [Hans Dietrich Software]

            M Offline
            M Offline
            MrWhiteboard
            wrote on last edited by
            #5

            This sounds pretty dangerous to me, but I know how it can be when you just have to do some things. You can declare a simple local variable and take its address, that will give you an address to begin working with. But you need to ensure that the variable does exist (not removed by optimizer) and you then need to make sure you understand the stack frame layouts under both x86 and x64, they aren't the same. Harry.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups