Getting stack address
-
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
-
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
In
x64
, theFS
register has been replaced by theGS
register. And you have to use compiler intrinsics instead of inline assembly. The following intrinsics will allow you to read from an offset in theGS
register.__readgsbyte
__readgsword
__readgsdword
__readgsqwordJust for completeness, there are also similar intrinsics available in
x86
to read from an offset of theFS
register -__readfsbyte
__readfsword
__readfsdword
__readfsqword«_Superman_»
I love work. It gives me something to do between weekends. -
In
x64
, theFS
register has been replaced by theGS
register. And you have to use compiler intrinsics instead of inline assembly. The following intrinsics will allow you to read from an offset in theGS
register.__readgsbyte
__readgsword
__readgsdword
__readgsqwordJust for completeness, there are also similar intrinsics available in
x86
to read from an offset of theFS
register -__readfsbyte
__readfsword
__readfsdword
__readfsqword«_Superman_»
I love work. It gives me something to do between weekends.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
-
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
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. -
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
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.