golang 获取exe、dll、apk 版本号
发布时间:2020-12-16 19:21:35 所属栏目:大数据 来源:网络整理
导读:通过go获取exe、dll、apk版本号,支持夸平台,可交叉编译。 一点都不爽,修改一个格式还要审核一下,浪费心情。 // golang 实现读取exe dll apk 版本号package mainimport ( "flag" "fmt" "log" "os" "path/filepath")import ( "github.com/lunny/axmlParser
通过go获取exe、dll、apk版本号,支持夸平台,可交叉编译。 一点都不爽,修改一个格式还要审核一下,浪费心情。 // 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:WindowsSystem32cmd.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),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) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |