golangexe, 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:\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 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
set containerThere is no built-in set container in Go How to implement Set struct{} => type struct{}{} => 0bytes How to create set :=...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.