duangu1033 2018-08-01 17:57
浏览 105

访问线程环境块时进入程序恐慌状态

I'm developing on a Go library to access some internal Windows thread structures (Thread Environment Block) and this requires writing some assembly code. I've been trying to understand why this works on a Win32 C++ application but it doesn't on my Go library.

This snippet of Go assembly code accesses fs:[0x18] to return a pointer to the thread's associated 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

This is the equivalent MASM code, which compiles and runs just fine on MSVC:

void* readfsdword(unsigned offset_)
{
    unsigned dw;

    __asm {
        mov eax, offset_
        mov eax, fs:[eax]
        mov dw, eax
    }

    return (void*)dw;
}

The Go program panics when accessing the returned pointer to the TEB. Here's the message I get:

panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x0 pc=0x498d5b]

The Go assembly code seems right to me, but I can't understand how and why the program panics. Any help is much appreciated!

Here's an example to reproduce the issue:

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

intrinsics.go

package nt

func ReadFsDword(offset uint32) (ret uint32)

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
}
  • 写回答

1条回答 默认 最新

  • doufu7464 2018-08-01 20:59
    关注

    The problem was fixed. Apparently, Windows uses the gs register with an offset of 0x30 on x64 whereas fs and a 0x18 offset are used on x86/WoW64 mode. The solution is to use either fs or gs with the respective offsets depending on the value of GOARCH.

    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)