1
0
mirror of https://github.com/zu1k/nali.git synced 2025-02-02 18:32:43 +08:00
This commit is contained in:
zu1k 2020-07-18 10:48:41 +08:00
parent a120e91d46
commit 035b8360f2
6 changed files with 97 additions and 101 deletions

View File

@ -21,7 +21,7 @@ var updateCmd = &cobra.Command{
filePath := filepath.Join(constant.HomePath, "qqwry.dat") filePath := filepath.Join(constant.HomePath, "qqwry.dat")
log.Println("正在下载最新纯真 IP 库...") log.Println("正在下载最新纯真 IP 库...")
tmpData, err := qqwry.GetOnline() tmpData, err := qqwry.Download()
if err != nil { if err != nil {
log.Fatalln("下载失败", err.Error()) log.Fatalln("下载失败", err.Error())
return return

View File

@ -1,6 +1,8 @@
package common package common
const ( const (
RedirectMode1 = 0x01 // one mode // RedirectMode1 [IP][0x01][国家和地区信息的绝对偏移地址]
RedirectMode2 = 0x02 //another mode RedirectMode1 = 0x01
// RedirectMode2 [IP][0x02][信息的绝对偏移][...] or [IP][国家][...]
RedirectMode2 = 0x02
) )

View File

@ -1,6 +1,5 @@
package common package common
// byteToUInt32 将 byte 转换为uint32
func ByteToUInt32(data []byte) uint32 { func ByteToUInt32(data []byte) uint32 {
i := uint32(data[0]) & 0xff i := uint32(data[0]) & 0xff
i |= (uint32(data[1]) << 8) & 0xff00 i |= (uint32(data[1]) << 8) & 0xff00

View File

@ -19,19 +19,19 @@ type QQwry struct {
// NewQQwry new db from path // NewQQwry new db from path
func NewQQwry(filePath string) QQwry { func NewQQwry(filePath string) QQwry {
var tmpData []byte var fileData []byte
var fileInfo common.FileInfo var fileInfo common.FileInfo
// 判断文件是否存在 // 判断文件是否存在
_, err := os.Stat(filePath) _, err := os.Stat(filePath)
if err != nil && os.IsNotExist(err) { if err != nil && os.IsNotExist(err) {
log.Println("文件不存在,尝试从网络获取最新纯真 IP 库") log.Println("文件不存在,尝试从网络获取最新纯真 IP 库")
tmpData, err = GetOnline() fileData, err = Download()
if err != nil { if err != nil {
panic(err) panic(err)
} else { } else {
if err := ioutil.WriteFile(filePath, tmpData, 0644); err == nil { if err := ioutil.WriteFile(filePath, fileData, 0644); err == nil {
log.Printf("已将最新的纯真 IP 保存到本地 %s ", filePath) log.Printf("已将最新的 纯真IP 保存到本地: %s ", filePath)
} }
} }
} else { } else {
@ -42,13 +42,12 @@ func NewQQwry(filePath string) QQwry {
} }
defer fileInfo.FileBase.Close() defer fileInfo.FileBase.Close()
tmpData, err = ioutil.ReadAll(fileInfo.FileBase) fileData, err = ioutil.ReadAll(fileInfo.FileBase)
if err != nil { if err != nil {
panic(err) panic(err)
} }
} }
fileInfo.Data = fileData
fileInfo.Data = tmpData
buf := fileInfo.Data[0:8] buf := fileInfo.Data[0:8]
start := binary.LittleEndian.Uint32(buf[:4]) start := binary.LittleEndian.Uint32(buf[:4])
@ -64,14 +63,14 @@ func NewQQwry(filePath string) QQwry {
} }
// Find ip地址查询对应归属地信息 // Find ip地址查询对应归属地信息
func (q QQwry) Find(ip string) (res string) { func (db QQwry) Find(ip string) (res string) {
if strings.Count(ip, ".") != 3 { if strings.Count(ip, ".") != 3 {
return return
} }
ip4 := binary.BigEndian.Uint32(net.ParseIP(ip).To4()) ip4 := binary.BigEndian.Uint32(net.ParseIP(ip).To4())
offset := q.searchIndex(ip4) offset := db.searchIndex(ip4)
if offset <= 0 { if offset <= 0 {
return return
} }
@ -79,27 +78,27 @@ func (q QQwry) Find(ip string) (res string) {
var gbkCountry []byte var gbkCountry []byte
var gbkArea []byte var gbkArea []byte
mode := q.ReadMode(offset + 4) mode := db.ReadMode(offset + 4)
// [IP][0x01][国家和地区信息的绝对偏移地址] // [IP][0x01][国家和地区信息的绝对偏移地址]
if mode == common.RedirectMode1 { if mode == common.RedirectMode1 {
countryOffset := q.ReadUInt24() countryOffset := db.ReadUInt24()
mode = q.ReadMode(countryOffset) mode = db.ReadMode(countryOffset)
if mode == common.RedirectMode2 { if mode == common.RedirectMode2 {
c := q.ReadUInt24() c := db.ReadUInt24()
gbkCountry = q.ReadString(c) gbkCountry = db.ReadString(c)
countryOffset += 4 countryOffset += 4
} else { } else {
gbkCountry = q.ReadString(countryOffset) gbkCountry = db.ReadString(countryOffset)
countryOffset += uint32(len(gbkCountry) + 1) countryOffset += uint32(len(gbkCountry) + 1)
} }
gbkArea = q.ReadArea(countryOffset) gbkArea = db.ReadArea(countryOffset)
} else if mode == common.RedirectMode2 { } else if mode == common.RedirectMode2 {
countryOffset := q.ReadUInt24() countryOffset := db.ReadUInt24()
gbkCountry = q.ReadString(countryOffset) gbkCountry = db.ReadString(countryOffset)
gbkArea = q.ReadArea(offset + 8) gbkArea = db.ReadArea(offset + 8)
} else { } else {
gbkCountry = q.ReadString(offset + 4) gbkCountry = db.ReadString(offset + 4)
gbkArea = q.ReadArea(offset + uint32(5+len(gbkCountry))) gbkArea = db.ReadArea(offset + uint32(5+len(gbkCountry)))
} }
enc := simplifiedchinese.GBK.NewDecoder() enc := simplifiedchinese.GBK.NewDecoder()
@ -110,24 +109,24 @@ func (q QQwry) Find(ip string) (res string) {
} }
// searchIndex 查找索引位置 // searchIndex 查找索引位置
func (q *QQwry) searchIndex(ip uint32) uint32 { func (db *QQwry) searchIndex(ip uint32) uint32 {
header := q.ReadData(8, 0) header := db.ReadData(8, 0)
start := binary.LittleEndian.Uint32(header[:4]) start := binary.LittleEndian.Uint32(header[:4])
end := binary.LittleEndian.Uint32(header[4:]) end := binary.LittleEndian.Uint32(header[4:])
buf := make([]byte, q.IndexLen) buf := make([]byte, db.IndexLen)
mid := uint32(0) mid := uint32(0)
_ip := uint32(0) _ip := uint32(0)
for { for {
mid = q.GetMiddleOffset(start, end) mid = db.GetMiddleOffset(start, end)
buf = q.ReadData(q.IndexLen, mid) buf = db.ReadData(db.IndexLen, mid)
_ip = binary.LittleEndian.Uint32(buf[:4]) _ip = binary.LittleEndian.Uint32(buf[:4])
if end-start == q.IndexLen { if end-start == db.IndexLen {
offset := common.ByteToUInt32(buf[4:]) offset := common.ByteToUInt32(buf[4:])
buf = q.ReadData(q.IndexLen) buf = db.ReadData(db.IndexLen)
if ip < binary.LittleEndian.Uint32(buf[:4]) { if ip < binary.LittleEndian.Uint32(buf[:4]) {
return offset return offset
} }

View File

@ -8,7 +8,43 @@ import (
"net/http" "net/http"
) )
func getKey() (uint32, error) { func Download() (data []byte, err error) {
resp, err := http.Get("https://qqwry.mirror.noc.one/qqwry.rar")
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
key, err := getCopyWriteKey()
if err != nil {
return nil, err
}
return unRar(body, key)
}
func unRar(data []byte, key uint32) ([]byte, error) {
for i := 0; i < 0x200; i++ {
key = key * 0x805
key++
key = key & 0xff
data[i] = byte(uint32(data[i]) ^ key)
}
reader, err := zlib.NewReader(bytes.NewReader(data))
if err != nil {
return nil, err
}
return ioutil.ReadAll(reader)
}
func getCopyWriteKey() (uint32, error) {
resp, err := http.Get("https://qqwry.mirror.noc.one/copywrite.rar") resp, err := http.Get("https://qqwry.mirror.noc.one/copywrite.rar")
if err != nil { if err != nil {
return 0, err return 0, err
@ -21,35 +57,3 @@ func getKey() (uint32, error) {
return binary.LittleEndian.Uint32(body[5*4:]), nil return binary.LittleEndian.Uint32(body[5*4:]), nil
} }
} }
// get db content from mirror
func GetOnline() ([]byte, error) {
resp, err := http.Get("https://qqwry.mirror.noc.one/qqwry.rar")
if err != nil {
return nil, err
}
defer resp.Body.Close()
if body, err := ioutil.ReadAll(resp.Body); err != nil {
return nil, err
} else {
if key, err := getKey(); err != nil {
return nil, err
} else {
for i := 0; i < 0x200; i++ {
key = key * 0x805
key++
key = key & 0xff
body[i] = byte(uint32(body[i]) ^ key)
}
reader, err := zlib.NewReader(bytes.NewReader(body))
if err != nil {
return nil, err
}
return ioutil.ReadAll(reader)
}
}
}

View File

@ -49,8 +49,8 @@ func NewZXwry(filePath string) ZXwry {
} }
} }
func (q ZXwry) Find(ip string) (result string) { func (db ZXwry) Find(ip string) (result string) {
q.Offset = 0 db.Offset = 0
tp := big.NewInt(0) tp := big.NewInt(0)
op := big.NewInt(0) op := big.NewInt(0)
@ -60,58 +60,50 @@ func (q ZXwry) Find(ip string) (result string) {
tp.SetString("FFFFFFFFFFFFFFFF", 16) tp.SetString("FFFFFFFFFFFFFFFF", 16)
op.And(op, tp) op.And(op, tp)
v6ip := op.Uint64() ipv6 := op.Uint64()
offset := q.searchIndex(v6ip) offset := db.searchIndex(ipv6)
country, area := db.getAddr(offset)
country, area := q.getAddr(offset)
if area == "ZX" {
area = ""
}
return fmt.Sprintf("%s %s", country, area) return fmt.Sprintf("%s %s", country, area)
} }
func (q *ZXwry) getAddr(offset uint32) (string, string) { func (db *ZXwry) getAddr(offset uint32) (string, string) {
mode := q.ReadMode(offset) mode := db.ReadMode(offset)
if mode == common.RedirectMode1 { if mode == common.RedirectMode1 {
// [IP][0x01][国家和地区信息的绝对偏移地址] offset = db.ReadUInt24()
offset = q.ReadUInt24() return db.getAddr(offset)
return q.getAddr(offset)
} }
// [IP][0x02][信息的绝对偏移][...] or [IP][国家][...] _offset := db.Offset - 1
_offset := q.Offset - 1 c1 := db.ReadArea(_offset)
c1 := q.ReadArea(_offset)
if mode == common.RedirectMode2 { if mode == common.RedirectMode2 {
q.Offset = 4 + _offset db.Offset = 4 + _offset
} else { } else {
q.Offset = _offset + uint32(1+len(c1)) db.Offset = _offset + uint32(1+len(c1))
} }
c2 := q.ReadArea(q.Offset) c2 := db.ReadArea(db.Offset)
return string(c1), string(c2) return string(c1), string(c2)
} }
func (q *ZXwry) searchIndex(ip uint64) uint32 { func (db *ZXwry) searchIndex(ip uint64) uint32 {
q.ItemLen = 8 db.ItemLen = 8
q.IndexLen = 11 db.IndexLen = 11
header := q.Data.Data[8:24] header := db.Data.Data[8:24]
start := binary.LittleEndian.Uint32(header[8:]) start := binary.LittleEndian.Uint32(header[8:])
counts := binary.LittleEndian.Uint32(header[:8]) counts := binary.LittleEndian.Uint32(header[:8])
end := start + counts*q.IndexLen end := start + counts*db.IndexLen
buf := make([]byte, q.IndexLen) buf := make([]byte, db.IndexLen)
for { for {
mid := q.GetMiddleOffset(start, end) mid := db.GetMiddleOffset(start, end)
buf = q.Data.Data[mid : mid+q.IndexLen] buf = db.Data.Data[mid : mid+db.IndexLen]
_ip := binary.LittleEndian.Uint64(buf[:q.ItemLen]) _ip := binary.LittleEndian.Uint64(buf[:db.ItemLen])
if end-start == q.IndexLen { if end-start == db.IndexLen {
if ip >= binary.LittleEndian.Uint64(q.Data.Data[end:end+q.ItemLen]) { if ip >= binary.LittleEndian.Uint64(db.Data.Data[end:end+db.ItemLen]) {
buf = q.Data.Data[end : end+q.IndexLen] buf = db.Data.Data[end : end+db.IndexLen]
} }
return common.ByteToUInt32(buf[q.ItemLen:]) return common.ByteToUInt32(buf[db.ItemLen:])
} }
if _ip > ip { if _ip > ip {
@ -119,7 +111,7 @@ func (q *ZXwry) searchIndex(ip uint64) uint32 {
} else if _ip < ip { } else if _ip < ip {
start = mid start = mid
} else if _ip == ip { } else if _ip == ip {
return common.ByteToUInt32(buf[q.ItemLen:]) return common.ByteToUInt32(buf[db.ItemLen:])
} }
} }
} }