未完成

构建模式是在go build打包二进制的时候指定的打包模式,通过go help buildmode查看支持的打包模式

$ go version

go version go1.18.1 linux/amd64

$ go help buildmode

The 'go build' and 'go install' commands take a -buildmode argument which
indicates which kind of object file is to be built. Currently supported values
are:

        -buildmode=archive
                Build the listed non-main packages into .a files. Packages named
                main are ignored.

        -buildmode=c-archive
                Build the listed main package, plus all packages it imports,
                into a C archive file. The only callable symbols will be those
                functions exported using a cgo //export comment. Requires
                exactly one main package to be listed.

        -buildmode=c-shared
                Build the listed main package, plus all packages it imports,
                into a C shared library. The only callable symbols will
                be those functions exported using a cgo //export comment.
                Requires exactly one main package to be listed.

        -buildmode=default
                Listed main packages are built into executables and listed
                non-main packages are built into .a files (the default
                behavior).

        -buildmode=shared
                Combine all the listed non-main packages into a single shared
                library that will be used when building with the -linkshared
                option. Packages named main are ignored.

        -buildmode=exe
                Build the listed main packages and everything they import into
                executables. Packages not named main are ignored.

        -buildmode=pie
                Build the listed main packages and everything they import into
                position independent executables (PIE). Packages not named
                main are ignored.

        -buildmode=plugin
                Build the listed main packages, plus all packages that they
                import, into a Go plugin. Packages not named main are ignored.

On AIX, when linking a C program that uses a Go archive built with
-buildmode=c-archive, you must pass -Wl,-bnoobjreorder to the C compiler.

<br/>

archive 模式

<br/>

shared 模式

<br/>

c-archive 模式

<br/>

c-shared 模式

<br/>

exe 模式

<br/>

pie 模式

是一种使用PIE技术的安全编译模式,能提供一定防反编译的防护能力(但也不能只寄望与一种技术,世界上没有绝对的技术)

PIE技术

PIE全称是position-independent executable,中文解释为地址无关可执行文件。

一般程序的代码段(.text)、数据段(.data)和全局变量段(.bss)加载时是一个固定的地址,而PIE技术就是使其每次加载程序时都会变换地址,所以提高了反编译的难度。

<br/>

plugin 模式

该模式会将非main包的go程序打包成可以热加载的插件。

==不过,目前使用这种模板打包插件还是有缺陷的,首先它不支持windows下打包和使用,其次插件不支持热卸载==

使用

插件要求是 编译插件的包名必须是main

hello.go

package main

import "fmt"

func Hello(say any) {
  fmt.Println("在hello里:",say)
}

编译:

go build -buildmode=plugin -o hello.so hello.go

使用:

type Hello func(say any)

func main() {
    p, err := plugin.Open("./plugin.so")
    if err != nil {
        log.Fatalln(err)
    }
    h, err := p.Lookup("Hello")
    if err != nil {
        log.Fatalln(err)
    }
    h.(Hello)("hello")
}

<br/>

<br/>

  • archive 模式,最终会编译出名为.a的静态文件,编译时会忽略main包(也就是会忽略main入口)。这种模式类似与c/c++程序的打包过程,将代码编译为二进制,但此时程序还不能直接运行。
  • c-archive 模式,生成c/c++的静态库,编译后会生成.a.h的c头文件,随后可将go程序一同编译进c程序。
  • c-shared 模式,与c-archive基本一致,区别是c-shared最终生成的是c/c++动态库。
  • default 模式,就是默认的模式,直接使用go build的时候就是使用此模式。
  • shared 模式,与archive基本一致,区别是shared生成的是go的动态库。
  • exe 模式,与default基本一致,区别是最终会生成exe文件。
  • pie 模式,会使编译后的文件更安全,使其无法轻易地反编译,主要是使用PIE技术。一般程序的代码段(.text)、数据段(.data)和全局变量段(.bss)是一个固定的地址,而PIE技术就是使其每次加载程序时都会变换地址,所以提高了反编译的难度。
  • plugin 模式,会生成go插件,可以在其他程序中热加载。
Last modification:May 5th, 2022 at 08:38 pm
如果觉得我的文章对你有用,请随意赞赏