温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

golang 获取exe、dll、apk 版本号

发布时间:2020-07-19 03:16:29 来源:网络 阅读:1703 作者:codyguo 栏目:开发技术
// golang 实现读取exe dll apk 版本号 package main import (     "flag"     "fmt"     "log"     "os"     "path/filepath" ) import (     "github.com/lunny/axmlParser" ) var (     file fileInfo ) const (     MZ       = "MZ"     PE       = "PE"     RSRC     = ".rsrc"     TYPET    = 16     PEOFFSET = 64     MACHINE  = 332     DEFAULT  = `C:\Windows\System32\cmd.exe` ) type fileInfo struct {     FilePath string     Version  string     Debug    bool } func (f *fileInfo) checkError(err error) {     if err != nil {         log.Fatalln(err)     } } // 获取exe dll版本 func (f *fileInfo) GetExeVersion() (err error) {     file, err := os.Open(f.FilePath)     f.checkError(err)     // 第一次读取64 byte     buffer := make([]byte, 64)     _, err = file.Read(buffer)     f.checkError(err)     defer file.Close()     str := string(buffer[0]) + string(buffer[1])     if str != MZ {         log.Fatalln("读取exe错误,找不到 MZ.", f.FilePath)     }     peOffset := f.unpack([]byte{buffer[60], buffer[61], buffer[62], buffer[63]})     if peOffset < PEOFFSET {         log.Fatalln("peOffset 读取错误.", f.FilePath)     }     // 读取从文件开头移位到 peOffset,第二次读取 24 byte     _, err = file.Seek(int64(peOffset), 0)     buffer = make([]byte, 24)     _, err = file.Read(buffer)     f.checkError(err)     str = string(buffer[0]) + string(buffer[1])     if str != PE {         log.Fatalln("读取exe错误,找不到 PE.", f.FilePath)     }     machine := f.unpack([]byte{buffer[4], buffer[5]})     if machine != MACHINE {         log.Fatalln("machine 读取错误.", f.FilePath)     }     noSections := f.unpack([]byte{buffer[6], buffer[7]})     optHdrSize := f.unpack([]byte{buffer[20], buffer[21]})     // 读取从当前位置移位到 optHdrSize,第三次读取 40 byte     file.Seek(int64(optHdrSize), 1)     resFound := false     for i := 0; i < int(noSections); i++ {         buffer = make([]byte, 40)         file.Read(buffer)         str = string(buffer[0]) + string(buffer[1]) + string(buffer[2]) + string(buffer[3]) + string(buffer[4])         if str == RSRC {             resFound = true             break         }     }     if !resFound {         log.Fatalln("读取exe错误,找不到 .rsrc.", f.FilePath)     }     infoVirt := f.unpack([]byte{buffer[12], buffer[13], buffer[14], buffer[15]})     infoSize := f.unpack([]byte{buffer[16], buffer[17], buffer[18], buffer[19]})     infoOff := f.unpack([]byte{buffer[20], buffer[21], buffer[22], buffer[23]})     // 读取从文件开头位置移位到 infoOff,第四次读取 infoSize byte     file.Seek(int64(infoOff), 0)     buffer = make([]byte, infoSize)     _, err = file.Read(buffer)     f.checkError(err)     nameEntries := f.unpack([]byte{buffer[12], buffer[13]})     idEntries := f.unpack([]byte{buffer[14], buffer[15]})     var infoFound bool     var subOff, i int64     for i = 0; i < (nameEntries + idEntries); i++ {         typeT := f.unpack([]byte{buffer[i*8+16], buffer[i*8+17], buffer[i*8+18], buffer[i*8+19]})         if typeT == TYPET {             infoFound = true             subOff = int64(f.unpack([]byte{buffer[i*8+20], buffer[i*8+21], buffer[i*8+22], buffer[i*8+23]}))             break         }     }     if !infoFound {         log.Fatalln("读取exe错误,找不到 typeT == 16.", f.FilePath)     }     subOff = subOff & 0x7fffffff     infoOff = f.unpack([]byte{buffer[subOff+20], buffer[subOff+21], buffer[subOff+22], buffer[subOff+23]}) //offset of first FILEINFO     infoOff = infoOff & 0x7fffffff     infoOff = f.unpack([]byte{buffer[infoOff+20], buffer[infoOff+21], buffer[infoOff+22], buffer[infoOff+23]}) //offset to data     dataOff := f.unpack([]byte{buffer[infoOff], buffer[infoOff+1], buffer[infoOff+2], buffer[infoOff+3]})     dataOff = dataOff - infoVirt     version1 := f.unpack([]byte{buffer[dataOff+48], buffer[dataOff+48+1]})     version2 := f.unpack([]byte{buffer[dataOff+48+2], buffer[dataOff+48+3]})     version3 := f.unpack([]byte{buffer[dataOff+48+4], buffer[dataOff+48+5]})     version4 := f.unpack([]byte{buffer[dataOff+48+6], buffer[dataOff+48+7]})     version := fmt.Sprintf("%d.%d.%d.%d", version2, version1, version4, version3)     f.Version = version     return nil } func (f *fileInfo) unpack(b []byte) (num int64) {     for i := 0; i < len(b); i++ {         num = 256*num + int64((b[len(b)-1-i] & 0xff))     }     return } // 获取 apk 版本 func (f *fileInfo) GetApkVersion() (err error) {     listener := new(axmlParser.AppNameListener)     _, err = axmlParser.ParseApk(f.FilePath, listener)     f.checkError(err)     f.Version = listener.VersionName     return nil } func init() {     flag.StringVar(&file.FilePath, "path", DEFAULT, "Get exe or dll or apk version information.")     flag.BoolVar(&file.Debug, "d", false, "if true print exe or dll file name.") } func main() {     flag.Parse()     suffix := filepath.Ext(file.FilePath)     switch suffix {     case ".exe", ".dll":         file.GetExeVersion()     case ".apk":         file.GetApkVersion()     default:         log.Fatalln("仅能获取exe、dll、apk版本号,请重新输入程序路径.", file.FilePath)     }     switch {     case file.Debug:         fmt.Printf("%s 的版本号为: ", file.FilePath)     case file.FilePath == DEFAULT:         flag.PrintDefaults()         fmt.Printf("%s 的版本号为: ", file.FilePath)     }     fmt.Printf("%s", file.Version) }


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI