NTA*_*ity 2 windows assembly go
我正在开发一个Go库来访问一些内部Windows线程结构(线程环境块),这需要编写一些汇编代码.我一直试图理解为什么它适用于Win32 C++应用程序,但它不在我的Go库上.
这个Go汇编代码片段访问fs:[0x18]以返回指向线程关联TEB的指针:
// func ReadFsDword(offset uint32) (dword uint32)
TEXT ·ReadFsDword(SB),$0-8
MOVL offset+0(FP), AX
// mov eax, dword ptr fs:[eax]
BYTE $0x64; BYTE $0x8B; BYTE $0x00
MOVL AX, ret+8(FP)
RET
Run Code Online (Sandbox Code Playgroud)
这是等效的MASM代码,可以在MSVC上编译和运行:
void* readfsdword(unsigned offset_)
{
unsigned dw;
__asm {
mov eax, offset_
mov eax, fs:[eax]
mov dw, eax
}
return (void*)dw;
}
Run Code Online (Sandbox Code Playgroud)
当访问返回指向TEB的指针时,Go程序会发生混乱.这是我得到的信息:
panic:运行时错误:无效的内存地址或nil指针取消引用[signal 0xc0000005 code = 0x0 addr = 0x0 pc = 0x498d5b]
Go汇编代码似乎对我而言,但我无法理解该程序如何以及为何会引起恐慌.任何帮助深表感谢!
这是重现问题的示例:
intrinsics.s
#include "textflag.h"
#include "funcdata.h"
// func ReadFsDword(offset uint32) (ret uint32)
TEXT ·ReadFsDword(SB),$0-8
MOVL offset+0(FP), AX
// mov eax, dword ptr fs:[eax]
BYTE $0x64; BYTE $0x8B; BYTE $0x00
MOVL AX, ret+8(FP)
RET
Run Code Online (Sandbox Code Playgroud)
intrinsics.go
package nt
func ReadFsDword(offset uint32) (ret uint32)
Run Code Online (Sandbox Code Playgroud)
test.go
package main
import "nt"
func main() {
GetProcAddress("LoadLibraryExW")
}
func GetProcAddress(proc string) unsafe.Pointer {
teb := nt.NtGetTeb()
fmt.Printf("%p", teb)
// todo: implement
return nil
}
Run Code Online (Sandbox Code Playgroud)
问题得到解决.显然,Windows gs在x64上使用偏移量为0x30 的寄存器,而fs在x86/WoW64模式下使用0x18偏移量.解决方案是根据值使用fs或gs使用相应的偏移量GOARCH.
| 归档时间: |
|
| 查看次数: |
90 次 |
| 最近记录: |