From ee21e355e3e427ded6b0b4de9e8935f2a363b6f0 Mon Sep 17 00:00:00 2001 From: 5icorgi <36869220+5icorgi@users.noreply.github.com> Date: Thu, 12 Nov 2020 15:55:23 +0800 Subject: [PATCH] Update main.go --- main.go | 162 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 109 insertions(+), 53 deletions(-) diff --git a/main.go b/main.go index 41e9e00..fa254d5 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,9 @@ import ( "crypto/rsa" "crypto/sha256" "crypto/x509" + "debug/elf" + "debug/macho" + "debug/pe" "encoding/base64" "encoding/hex" "encoding/json" @@ -75,19 +78,13 @@ xMNjyLp1b84s2VVXTpSFA7i6KEUhl4NjqhZTslJht5Dfiy2Mmvfk2so= var ( licenseName string originLicense string - xrayPath string + xrayFilePath string ) func main() { - validTime, _ := time.Parse("2006-01-02 15:04:05", "2021-01-01 00:00:00") - nowTime := time.Now() - if nowTime.After(validTime) { - panic("本工具已失效") - } - flag.StringVar(&licenseName, "g", "", "生成一个永久license,需要指定用户名") flag.StringVar(&originLicense, "p", "", "解析官方证书,需要指定证书路径") - flag.StringVar(&xrayPath, "c", "", "patch xray,需要指定xray程序文件路径") + flag.StringVar(&xrayFilePath, "c", "", "patch xray,需要指定xray程序文件路径") flag.Parse() @@ -99,47 +96,10 @@ func main() { genNew(licenseName) } - if xrayPath != "" { - patchXray(xrayPath) + if xrayFilePath != "" { + patch(xrayFilePath) } -} -func patchXray(filePath string) { - var ( - originBytes []byte - newBytes []byte - ) - origin, err := ioutil.ReadFile(filePath) - if err != nil { - panic(err) - } - //x86特征码: 0F 95 C0 83 F0 01 88 44 24 50 83 C4 30 C3 - originX86Bytes := []byte{0x0F, 0x95, 0xC0, 0x83, 0xF0, 0x01, 0x88, 0x44, 0x24, 0x50, 0x83, 0xC4, 0x30, 0xC3} - newX86Bytes := []byte{0x0F, 0x94, 0xC0, 0x83, 0xF0, 0x01, 0x88, 0x44, 0x24, 0x50, 0x83, 0xC4, 0x30, 0xC3} - loc := bytes.LastIndex(origin, originX86Bytes) - //x64特征码: 0F 94 84 24 A8 00 00 00 - if loc == -1 { - originX64Bytes := []byte{0x0F, 0x94, 0x84, 0x24, 0xA8, 0x00, 0x00, 0x00} - newX64Bytes := []byte{0x0F, 0x95, 0x84, 0x24, 0xA8, 0x00, 0x00, 0x00} - loc = bytes.LastIndex(origin, originX64Bytes) - if loc == -1 { - fmt.Println("Patch failed: maybe already patched.") - os.Exit(0) - } - originBytes = originX64Bytes - newBytes = newX64Bytes - } else { - originBytes = originX86Bytes - newBytes = newX86Bytes - } - - fmt.Printf("Signature index: %#x\n", loc) - - newFile := bytes.ReplaceAll(origin, originBytes, newBytes) - err = ioutil.WriteFile(filePath, newFile, os.ModePerm) - if err == nil { - fmt.Println("Patch success:", filePath) - } } func parseAlready(licenseFile string) { @@ -173,9 +133,6 @@ func parseAlready(licenseFile string) { fmt.Println("version ok: 2") } - //fmt.Printf("pre 17: %x\n", base64DecodeData[:17]) - //fmt.Printf("pre 17: %x\n", pre17Bytes) - //解密前有一个简单的变换处理 right := len(base64DecodeData) - 1 for l := 1; l < right; l++ { @@ -188,7 +145,7 @@ func parseAlready(licenseFile string) { //fmt.Println("trans bytes:", hex.EncodeToString(base64DecodeData)) // aes解密license - // 总长度 487,前面17个字节是单独加上的,所以总共解密出 480个字节的数据 + // | 1B : version | 16B : aes iv | 480B : cipher | aesDecData, err := Decrypt(base64DecodeData[17:], base64DecodeData[1:17]) if err != nil { panic(err) @@ -294,8 +251,6 @@ func genNew(name string) { # user_name: Chinese # distribution: COMMUNITY-ADVANCED # 仅对修改后的xray有效 - - ` + licenseText + ` ` @@ -363,3 +318,104 @@ func importPrivateKey(key string) *rsa.PrivateKey { } return privateKey } + +var ( + origin386Bytes, _ = hex.DecodeString("0F95C083F0018844245083C430C3") + new386Bytes, _ = hex.DecodeString("0F94C083F0018844245083C430C3") + originAmd64Bytes, _ = hex.DecodeString("000F84BE020000") + newAmd64Bytes, _ = hex.DecodeString("000F85BE020000") + originArmBytes, _ = hex.DecodeString("000050E30000A0E30100A013010020E254") + newArmBytes, _ = hex.DecodeString("000050E30000A0E30100A0130100A0E354") + originAArch64Bytes, _ = hex.DecodeString("1F001FEBE0079F9A000040D2E0C3") + newAArch64Bytes, _ = hex.DecodeString("1F001FEBE0079F9A200080D2E0C3") +) + +func patch(filePath string) { + var ( + originBytes []byte + newBytes []byte + maxIndex uint64 = 0 + ) + + if elfFile, err := elf.Open(filePath); err == nil { + switch elfFile.Machine { + case elf.EM_386: + fmt.Println("linux 386") + originBytes = origin386Bytes + newBytes = new386Bytes + case elf.EM_X86_64: + fmt.Println("linux amd64") + originBytes = originAmd64Bytes + newBytes = newAmd64Bytes + case elf.EM_ARM: + fmt.Println("linux arm") + originBytes = originArmBytes + newBytes = newArmBytes + case elf.EM_AARCH64: + fmt.Println("linux arm64") + originBytes = originAArch64Bytes + newBytes = newAArch64Bytes + default: + fmt.Println("Unsupported linux platform!!") + } + sections := elfFile.Sections + for _, i := range sections { + if i.Name == ".text" { + maxIndex = i.Addr + i.Size + fmt.Printf("[.text] offset: %#x, addr: %#x-%#x\n", i.Offset, i.Addr, maxIndex) + } + } + } else if peFile, err := pe.Open(filePath); err == nil { + switch peFile.Machine { + case pe.IMAGE_FILE_MACHINE_AMD64: + fmt.Println("windows amd64") + originBytes = originAmd64Bytes + newBytes = newAmd64Bytes + case pe.IMAGE_FILE_MACHINE_I386: + fmt.Println("windows i386") + originBytes = origin386Bytes + newBytes = new386Bytes + default: + fmt.Println("Unsupported windows platform!!") + + } + } else if machoFile, err := macho.Open(filePath); err == nil { + switch machoFile.Cpu { + case macho.CpuAmd64: + fmt.Println("darwin amd64") + originBytes = originAmd64Bytes + newBytes = newAmd64Bytes + case macho.Cpu386: + fmt.Println("darwin 386") + originBytes = origin386Bytes + newBytes = new386Bytes + default: + fmt.Println("Unsupported darwin platform!!") + } + } else { + fmt.Println("Can NOT parse file") + return + } + + origin, err := ioutil.ReadFile(filePath) + loc := bytes.LastIndex(origin, originBytes) + + if loc > 0 { + fmt.Printf("Signature index: %#x\n", loc) + newFile := replace(origin, newBytes, loc) + err = ioutil.WriteFile(filePath, newFile, os.ModePerm) + if err == nil { + fmt.Println("Patch success:", filePath) + } + } else { + fmt.Println("Can't find signature") + } +} + +func replace(origin, new []byte, index int) []byte { + n := make([]byte, len(origin)) + copy(n[:index], origin[:index]) + copy(n[index:index+len(new)], new) + copy(n[index+len(new):], origin[index+len(new):]) + return n +}