Skip to content

Instantly share code, notes, and snippets.

@diamondo25
Created July 31, 2015 21:44
Show Gist options
  • Save diamondo25/004d96d178c84bdbbcdd to your computer and use it in GitHub Desktop.
Save diamondo25/004d96d178c84bdbbcdd to your computer and use it in GitHub Desktop.
Golang MapleStory Exepatch/MapleStory(t).exe version identifier
package main
import (
"encoding/hex"
"flag"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
)
func main() {
var input string
flag.StringVar(&input, "input", "", "Input file")
flag.Parse()
fmt.Println("MapleStory ExePatch.dat Identifier and Mover v1.3.3.7-patch2-alpha")
file, err := os.Open(input)
if err != nil {
panic(err)
}
// Read from back to front, 2048 bytes at a time
size := 2048
buffer := make([]byte, size)
magicValue1 := [8]byte{0xBD, 0x04, 0xEF, 0xFE, 0x00, 0x00, 0x01, 0x00}
/*
magicValue2 := [...]byte{
0x56, 0x00, 0x53, 0x00, 0x5F, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00, 0x53, 0x00, 0x49, 0x00,
0x4F, 0x00, 0x4E, 0x00, 0x5F, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x46, 0x00, 0x4F, 0x00} // VS_VERSION_INFO
*/
offset := 0
for {
offset += len(buffer)
_, err := file.Seek(int64(offset), os.SEEK_SET)
if err != nil {
fmt.Println("File seek error", err)
break
}
amount, err := file.Read(buffer)
if err != nil {
fmt.Println("File read error", err)
break
}
matching := true
idx := 0
for ; idx < amount; idx++ {
matching = true
for idx2, b2 := range magicValue1 {
bufferOffset := idx + idx2
if bufferOffset >= amount {
// No more data to compare
matching = false
break
}
b := buffer[bufferOffset]
if b2 != b {
// We don't have a match
matching = false
}
}
if matching {
break
}
}
if !matching {
continue
}
// Cool. Now check the version info
file.Seek(int64(offset+idx+8), os.SEEK_SET)
buffer = make([]byte, 8)
file.Read(buffer)
version := uint16(buffer[0] | buffer[1]<<8)
//locale := uint16(buffer[2] | buffer[3] << 8)
subversion := uint16(buffer[6] | buffer[7]<<8)
fmt.Println(hex.Dump(buffer))
fmt.Println("Found version:", version, "subversion", subversion)
fileInfo, err := file.Stat()
if err != nil {
panic(err)
}
outputFilename := filepath.Join(filepath.Dir(input), fmt.Sprintf("MapleStory-v%d.%d.exe", version, subversion))
fmt.Println("Writing to", outputFilename)
// Time to copy
b, err := ioutil.ReadFile(input)
if err != nil {
panic(err)
}
// write whole the body
err = ioutil.WriteFile(outputFilename, b, 0644)
if err != nil {
panic(err)
}
modTime := fileInfo.ModTime()
timeString := fmt.Sprintf("%04d%02d%02d%02d%02d.%02d", modTime.Year(), modTime.Month(), modTime.Day(), modTime.Hour(), modTime.Minute(), modTime.Second())
// Copy modification time
cmd := exec.Command("touch", "-t", timeString, outputFilename)
cmd.Run()
break
}
file.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment