|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"b612.me/wincmd"
|
|
|
|
|
"b612.me/wincmd/ntfs/mft"
|
|
|
|
|
"b612.me/wincmd/ntfs/usn"
|
|
|
|
|
"b612.me/wincmd/ntfs/utf16"
|
|
|
|
|
"encoding/binary"
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"log"
|
|
|
|
|
_ "net/http/pprof"
|
|
|
|
|
"regexp"
|
|
|
|
|
"runtime"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
f, size, err := mft.GetMFTFile(`C:\`)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
recordSize := int64(1024)
|
|
|
|
|
i := int64(0)
|
|
|
|
|
fmt.Println("start size is", size)
|
|
|
|
|
alreadyGot := int64(0)
|
|
|
|
|
maxRecordSize := size / recordSize
|
|
|
|
|
if maxRecordSize > 1024 {
|
|
|
|
|
maxRecordSize = 1024
|
|
|
|
|
}
|
|
|
|
|
for {
|
|
|
|
|
for {
|
|
|
|
|
if (size - alreadyGot) < maxRecordSize*recordSize {
|
|
|
|
|
maxRecordSize--
|
|
|
|
|
} else {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if maxRecordSize < 10 {
|
|
|
|
|
maxRecordSize = 1
|
|
|
|
|
}
|
|
|
|
|
buf := make([]byte, maxRecordSize*recordSize)
|
|
|
|
|
got, err := io.ReadFull(f, buf)
|
|
|
|
|
if err != nil {
|
|
|
|
|
if errors.Is(err, io.EOF) {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
log.Fatalln("Unable to read record data", err)
|
|
|
|
|
}
|
|
|
|
|
alreadyGot += int64(got)
|
|
|
|
|
for j := int64(0); j < 1024*maxRecordSize; j += 1024 {
|
|
|
|
|
record, err := mft.ParseRecord(buf[j : j+1024])
|
|
|
|
|
if err != nil {
|
|
|
|
|
// fmt.Println("Unable to parse MFT record", err)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fname := record.FindAttributes(mft.AttributeTypeFileName)
|
|
|
|
|
|
|
|
|
|
for _, v := range fname {
|
|
|
|
|
if (record.Flags&mft.RecordFlagIsIndex)>>3 == 0 && record.Flags&mft.RecordFlagInUse == 1 {
|
|
|
|
|
filename := utf16.DecodeString(v.Data[66:], binary.LittleEndian)
|
|
|
|
|
//data:=utf16.DecodeString(v.Data, binary.LittleEndian)
|
|
|
|
|
if filename != "" {
|
|
|
|
|
attbr := record.FindAttributes(mft.AttributeTypeStandardInformation)
|
|
|
|
|
if len(attbr) == 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
stand, _ := mft.ParseStandardInformation(attbr[0].Data)
|
|
|
|
|
if stand.FileAttributes&mft.FileAttributeNormal == 1 {
|
|
|
|
|
i++
|
|
|
|
|
}
|
|
|
|
|
//oo:=record.FindAttributes(mft.AttributeTypeData)
|
|
|
|
|
//if len(oo)!=0 {
|
|
|
|
|
// fmt.Println(oo[0].ActualSize)
|
|
|
|
|
//}
|
|
|
|
|
//r := binutil.NewLittleEndianReader(v.Data[:8])
|
|
|
|
|
//fmt.Println(record.FileReference.ToUint64(), r.Uint64(0))
|
|
|
|
|
//fmt.Println(filename)
|
|
|
|
|
//log.Println("Read MFT record")
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fmt.Println(i)
|
|
|
|
|
|
|
|
|
|
//go http.ListenAndServe("0.0.0.0:8888", nil)
|
|
|
|
|
fmt.Println("开始获取Windows磁盘列表")
|
|
|
|
|
lists, err := wincmd.ListDrivers()
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
info := []usn.DiskInfo{}
|
|
|
|
|
for _, v := range lists {
|
|
|
|
|
data, err := wincmd.GetDiskInfo(v)
|
|
|
|
|
if err != nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("获取到磁盘信息:", data)
|
|
|
|
|
info = append(info, data)
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("忽略非NTFS磁盘")
|
|
|
|
|
var m runtime.MemStats
|
|
|
|
|
for _, v := range info {
|
|
|
|
|
if v.Format == "NTFS" && v.Driver == `C:\` {
|
|
|
|
|
|
|
|
|
|
fmt.Println("开始获取NTFS USN日志,磁盘:", v.Driver)
|
|
|
|
|
fileLists, err := usn.ListUsnFileFn(v.Driver, func(name string, typed bool) bool {
|
|
|
|
|
return true
|
|
|
|
|
if ok, _ := regexp.MatchString(`\.exe$`, name); ok {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
fmt.Println(len(fileLists))
|
|
|
|
|
return
|
|
|
|
|
for k, _ := range fileLists {
|
|
|
|
|
fmt.Println(k)
|
|
|
|
|
}
|
|
|
|
|
runtime.ReadMemStats(&m)
|
|
|
|
|
log.Printf("Alloc = %v TotalAlloc = %v Sys = %v NumGC = %v\n", m.Alloc/1024, m.TotalAlloc/1024, m.Sys/1024, m.NumGC)
|
|
|
|
|
runtime.GC()
|
|
|
|
|
p := time.After(time.Second * 86400)
|
|
|
|
|
for {
|
|
|
|
|
select {
|
|
|
|
|
case <-p:
|
|
|
|
|
return
|
|
|
|
|
case <-time.After(time.Second * 10):
|
|
|
|
|
runtime.ReadMemStats(&m)
|
|
|
|
|
log.Printf("Alloc = %v TotalAlloc = %v Sys = %v NumGC = %v\n", m.Alloc/1024, m.TotalAlloc/1024, m.Sys/1024, m.NumGC)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|