package main
import
(
"context"
"fmt"
"io"
"os"
"path"
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"
"github.com/gentlemanautomaton/volmgmt/usn"
"github.com/gentlemanautomaton/volmgmt/volume"
)
/
/
查询文件大小
func getFileSize(
file
*
os.
File
) (int64, error) {
fileInfo, err :
=
file
.Stat()
if
err !
=
nil {
return
0
, fmt.Errorf(
"failed to get file info:%v"
, err)
}
return
fileInfo.Size(), nil
}
/
/
读取ProgramID
func readProgramID(
file
*
os.
File
, fileSize int64) ([]byte, error) {
bufferSize :
=
8
_, err :
=
file
.Seek(fileSize
-
int64(bufferSize), io.SeekStart)
if
err !
=
nil {
return
nil, fmt.Errorf(
"faled to seek file:%v"
, err)
}
programId :
=
make([]byte, bufferSize)
_, err
=
file
.Read(programId)
if
err !
=
nil && err !
=
io.EOF {
return
nil, fmt.Errorf(
"failed to read program id:%v"
, err)
}
return
programId, nil
}
/
/
读取文件名
func readFileName(
file
*
os.
File
, fileSize int64) (
int
, []byte, error) {
bufferSize :
=
4
/
/
跳转到文件名长度位置
_, err :
=
file
.Seek(fileSize
-
12
, io.SeekStart)
if
err !
=
nil {
return
0
, nil, fmt.Errorf(
"failed to seek file:%v"
, err)
}
/
/
从文件中读取文件名长度
nameLenBytes :
=
make([]byte, bufferSize)
_, err
=
file
.Read(nameLenBytes)
if
err !
=
nil && err !
=
io.EOF {
return
0
, nil, fmt.Errorf(
"failed to read name length:%v"
, err)
}
/
/
计算文件名长度
nameLen :
=
0
for
_, b :
=
range
nameLenBytes {
nameLen
+
=
int
(b)
}
/
/
跳转到文件名位置
_, err
=
file
.Seek(fileSize
-
12
-
int64(nameLen), io.SeekStart)
if
err !
=
nil {
return
0
, nil, fmt.Errorf(
"failed to seek file:%v"
, err)
}
/
/
读取文件名
bufferSize
=
nameLen
fileName :
=
make([]byte, bufferSize)
_, err
=
file
.Read(fileName)
if
err !
=
nil && err !
=
io.EOF {
return
0
, nil, fmt.Errorf(
"failed to read name:%v"
, err)
}
return
nameLen, fileName, nil
}
/
/
解密文件
func decrypt(filePathTemp string, wg
*
sync.WaitGroup) error {
defer wg.Done()
var mut sync.Mutex
mut.Lock()
defer mut.Unlock()
/
/
获得目录
baseDirPath :
=
filepath.
Dir
(filePathTemp)
file
, err :
=
os.OpenFile(filePathTemp, os.O_RDWR, os.ModePerm)
if
err !
=
nil {
return
fmt.Errorf(
"open file %s,err:%v"
, filePathTemp, err)
}
/
/
结束自动关闭
defer
file
.Close()
/
/
获取文件大小
fileSize, err :
=
getFileSize(
file
)
if
err !
=
nil {
return
err
}
/
/
获得programID
programID, err :
=
readProgramID(
file
, fileSize)
if
err !
=
nil {
/
/
输出programId
println(programID)
return
err
}
/
/
读取文件名
nameLen, fileName, err :
=
readFileName(
file
, fileSize)
if
err !
=
nil {
return
err
}
/
/
计算出的文件名
fileNameStr :
=
string(fileName)
/
/
println(fileNameStr)
/
/
读取加密内容
_, err
=
file
.Seek(
0
, io.SeekStart)
if
err !
=
nil {
return
fmt.Errorf(
"failed to seek file:%v"
, err)
}
var chiper []byte
/
/
判断文件长度,如果小于加密长度
if
fileSize
-
12
-
int64(nameLen) <
0x2000
{
/
/
取文件前加密内容
chiperLen :
=
fileSize
-
12
-
int64(nameLen)
chiper
=
make([]byte, chiperLen)
}
else
{
chiper
=
make([]byte,
0x2000
)
}
_, err
=
file
.Read(chiper)
if
err !
=
nil && err !
=
io.EOF {
panic(err)
}
/
/
解密
var encryptionKey
=
[]byte{
61
,
33
,
125
,
145
,
168
,
153
,
200
,
93
,
}
var encryptionIV
=
[]byte{
70
,
69
,
195
,
247
,
191
,
147
,
238
,
160
,
}
var message []byte
for
x :
=
0
; x <
len
(chiper)
/
8
; x
+
+
{
for
i :
=
0
; i <
8
; i
+
+
{
encryptionIV[i]
=
(encryptionIV[i] ^ encryptionKey[i]
+
13
) &
0xFF
}
for
i :
=
0
; i <
8
; i
+
+
{
message
=
append(message, chiper[i
+
8
*
x]^encryptionIV[i])
}
}
for
i :
=
0
; i <
8
; i
+
+
{
encryptionIV[i]
=
(encryptionIV[i] ^ encryptionKey[i]
+
13
) &
0xFF
}
/
/
跳转到开始位置
_, err
=
file
.Seek(
0
, io.SeekStart)
if
err !
=
nil {
panic(err)
}
_, err
=
file
.Write(message)
if
err !
=
nil {
fmt.Println(
"写入文件失败"
)
}
/
/
跳转至文件名位置
_, err
=
file
.Seek(fileSize
-
12
-
int64(nameLen), io.SeekStart)
if
err !
=
nil {
panic(err)
}
/
/
修改文件名
file
.Close()
fileNameFull :
=
filepath.Join(baseDirPath, fileNameStr)
os.Rename(filePathTemp, fileNameFull)
/
/
把恶意写入的文件尾截掉
err
=
os.Truncate(fileNameFull, fileSize
-
12
-
int64(nameLen))
if
err !
=
nil {
fmt.Println(
"清理加密文件尾写入的数据截取失败"
)
}
fmt.Println(fileNameFull,
"解密完成"
)
return
nil
}
func main() {
/
/
设置协程最大数
runtime.GOMAXPROCS(runtime.NumCPU())
/
/
获得所有盘符
var wg sync.WaitGroup
logicalDrives :
=
GetLogicalDrives()
for
_, logicalDrivesItem :
=
range
logicalDrives {
/
/
循环
files :
=
FindFileWin(logicalDrivesItem
+
":\\"
)
for
_, filePath :
=
range
files {
wg.Add(
1
)
/
/
decrypt(filePath, &wg)
go decrypt(filePath, &wg)
}
}
wg.Wait()
/
*
err :
=
es.EverythingSetSearch(
"*.live"
)
if
err !
=
nil {
fmt.Printf(
"EverythingSetSearch:%v\n"
, err)
return
}
err
=
es.EverythingSetMax(
5
)
if
err !
=
nil {
fmt.Printf(
"EverythingSetMax:%v\n"
, err)
return
}
/
/
设置需要查询的内容
err
=
es.EverythingSetRequestFlags(es.EverythingRequestFileName | es.EverythingRequestPath |
es.EverythingRequestDateCreated | es.EverythingRequestDateModified | es.EverythingRequestDateAccessed |
es.EverythingRequestSize)
if
err !
=
nil {
fmt.Printf(
"EverythingSetRequestFlags:%v\n"
, err)
return
}
/
/
定义排序规则
err
=
es.EverythingSetSort(es.EverythingSortDateModifiedAscending)
if
err !
=
nil {
fmt.Printf(
"EverythingSetSort:%v\n"
, err)
return
}
/
/
开始查询
fmt.Println(
"EverythingQuery:"
, es.EverythingQuery(true))
/
/
得到结果个数
num, err :
=
es.EverythingGetNumResults()
if
err !
=
nil {
fmt.Printf(
"EverythingGetNumResults:%v\n"
, err)
return
}
var wg sync.WaitGroup
for
i :
=
uint32(
0
); i < num; i
+
+
{
wg.Add(
1
)
filePath, err :
=
es.EverythingGetResultFullPathName(i)
if
err !
=
nil {
fmt.Printf(
"EverythingGetResultFullPathName:%v\n"
, err)
return
}
go decrypt(filePath, &wg)
}
wg.Wait()
*
/
/
/
var wg sync.WaitGroup
/
/
wg.Add(
1
)
/
/
decrypt(
"C:\\DATA\\"
, &wg)
fmt.Println(
"所有文件解密成功"
)
}
func bitsToDrives(bitMap uint32) (drives []string) {
availableDrives :
=
[]string{
"A"
,
"B"
,
"C"
,
"D"
,
"E"
,
"F"
,
"G"
,
"H"
,
"I"
,
"J"
,
"K"
,
"L"
,
"M"
,
"N"
,
"O"
,
"P"
,
"Q"
,
"R"
,
"S"
,
"T"
,
"U"
,
"V"
,
"W"
,
"X"
,
"Y"
,
"Z"
}
for
i :
=
range
availableDrives {
if
bitMap&
1
=
=
1
{
drives
=
append(drives, availableDrives[i])
}
bitMap >>
=
1
}
return
}
/
/
获得所有盘符
func GetLogicalDrives() []string {
kernel32, _ :
=
syscall.LoadLibrary(
"kernel32.dll"
)
getLogicalDrivesHandle, _ :
=
syscall.GetProcAddress(kernel32,
"GetLogicalDrives"
)
var drives []string
if
ret, _, callErr :
=
syscall.Syscall(uintptr(getLogicalDrivesHandle),
0
,
0
,
0
,
0
); callErr !
=
0
{
/
/
handle error
}
else
{
drives
=
bitsToDrives(uint32(ret))
}
return
drives
}
/
/
查询Windows下文件
func FindFileWin(
dir
string) []string {
list
:
=
make([]string,
0
)
vol, err :
=
volume.New(
dir
+
"\\"
)
if
err !
=
nil {
fmt.Println(
"xxxxxx"
, err)
return
list
}
defer vol.Close()
mft :
=
vol.MFT()
defer mft.Close()
iter
, err :
=
mft.
Enumerate
(nil, usn.
Min
, usn.
Max
)
if
err !
=
nil {
fmt.Println(
"xxasdasd"
, err)
return
list
}
defer
iter
.Close()
cache :
=
usn.NewCache()
ctx :
=
context.Background()
err
=
cache.ReadFrom(ctx,
iter
)
if
err !
=
nil {
return
list
}
/
/
读取到的文件名
records :
=
cache.Records()
for
_, record :
=
range
records {
filesuffix :
=
path.Ext(record.Path)
/
/
搜索后缀名,不包含回收站
if
strings.ToUpper(filesuffix)
=
=
".LIVE"
&& !strings.Contains(record.Path,
"$Recycle.Bin"
) && !strings.Contains(record.Path,
"System Volume Information"
) {
fullFilePath :
=
filepath.Join(
dir
, record.Path)
list
=
append(
list
, fullFilePath)
}
}
return
list
}