Compare commits
4 Commits
abd754e22d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03f2eeef09 | ||
|
|
6745820f71 | ||
|
|
a2b8c67064 | ||
|
|
646e89dbee |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -24,4 +24,4 @@ go.work.sum
|
|||||||
|
|
||||||
# env file
|
# env file
|
||||||
.env
|
.env
|
||||||
|
.DS_Store
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
# MFTECmd
|
# MFTECmd
|
||||||
|
|
||||||
[] []
|
[](https://go.dev/) [](https://github.com/EricZimmerman/MFTECmd)
|
||||||
|
|
||||||
Утилита является портированной под Linux версией утилиты [Эрика Циммермана](https://github.com/EricZimmerman). При портировании была пересмотрена структура флагов и для более простого взаимодействия с программой.
|
Утилита является портированной под Linux версией утилиты [Эрика Циммермана](https://github.com/EricZimmerman). При портировании была пересмотрена структура флагов для более простого взаимодействия с программой.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Поддерживаемые форматы файлов
|
## Поддерживаемые форматы файлов
|
||||||
В качестве входных файлов утилита поддерживает:
|
В качестве входных файлов утилита поддерживает:
|
||||||
- `$MFT` - системный файл в файловой системе NTFS, в котором хранится информация о содержимом тома.
|
- `$MFT` - системный файл в файловой системе NTFS, в котором хранится информация о содержимом тома.
|
||||||
- `$J` (USN Journal) -системный файл в файловой системе NTFS, который хранит журнал изменений на томе.
|
- `$J` (USN Journal) - системный файл в файловой системе NTFS, который хранит журнал изменений на томе.
|
||||||
- `$Boot` - системный файл в файловой системе NTFS, содержащий загрузочный сектор и код запуска.
|
- `$Boot` - системный файл в файловой системе NTFS, содержащий загрузочный сектор и код запуска.
|
||||||
- `$SDS` - системный файл в файловой системе NTFS, содержит список дескрипторов безопасности для всех файлов и каталогов на томе.
|
- `$SDS` - системный файл в файловой системе NTFS, содержит список дескрипторов безопасности для всех файлов и каталогов на томе.
|
||||||
- `$I30` - атрибут индекса размещения. Связан с каталогами и содержит информацию о файлах и подкаталогах, содержащихся в каталоге.
|
- `$I30` - атрибут индекса размещения. Связан с каталогами и содержит информацию о файлах и подкаталогах, содержащихся в каталоге.
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -111,3 +113,99 @@ func ValidateLeaf(cmd any) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Валидация путей.
|
||||||
|
// Принимает на вход объект и при наличии метода Enabled производит валидацию
|
||||||
|
func ValidatePath(cmd any) error {
|
||||||
|
switch v := cmd.(type) {
|
||||||
|
case interface{ Enabled() error }:
|
||||||
|
return v.Enabled()
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяет, что у команды с output-блоками включён хотя бы один вывод.
|
||||||
|
func ValidateOutput(cmd any) error {
|
||||||
|
if cmd == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v := reflect.ValueOf(cmd)
|
||||||
|
if v.Kind() == reflect.Pointer {
|
||||||
|
if v.IsNil() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Kind() != reflect.Struct {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasOutputBlocks bool
|
||||||
|
var hasEnabledOutput bool
|
||||||
|
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
field := v.Field(i)
|
||||||
|
fieldType := v.Type().Field(i)
|
||||||
|
|
||||||
|
switch fieldType.Type {
|
||||||
|
case reflect.TypeOf(CSVOutput{}):
|
||||||
|
hasOutputBlocks = true
|
||||||
|
if enabled, ok := callEnabled(field); ok && enabled {
|
||||||
|
hasEnabledOutput = true
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.TypeOf(JSONOutput{}):
|
||||||
|
hasOutputBlocks = true
|
||||||
|
if enabled, ok := callEnabled(field); ok && enabled {
|
||||||
|
hasEnabledOutput = true
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.TypeOf(BodyOutput{}):
|
||||||
|
hasOutputBlocks = true
|
||||||
|
if enabled, ok := callEnabled(field); ok && enabled {
|
||||||
|
hasEnabledOutput = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasOutputBlocks && !hasEnabledOutput {
|
||||||
|
return errors.New("you must specify at least one output path: --csv, --json or --body")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вызов Enabled у поля
|
||||||
|
// Возвращает результат Enabled() и флаг успешности поиска метода
|
||||||
|
func callEnabled(v reflect.Value) (bool, bool) {
|
||||||
|
if !v.IsValid() {
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Пробуем метод у самого значения
|
||||||
|
if method := v.MethodByName("Enabled"); method.IsValid() {
|
||||||
|
if method.Type().NumIn() == 0 &&
|
||||||
|
method.Type().NumOut() == 1 &&
|
||||||
|
method.Type().Out(0).Kind() == reflect.Bool {
|
||||||
|
out := method.Call(nil)
|
||||||
|
return out[0].Bool(), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Пробуем метод у указателя
|
||||||
|
if v.CanAddr() {
|
||||||
|
if method := v.Addr().MethodByName("Enabled"); method.IsValid() {
|
||||||
|
if method.Type().NumIn() == 0 &&
|
||||||
|
method.Type().NumOut() == 1 &&
|
||||||
|
method.Type().Out(0).Kind() == reflect.Bool {
|
||||||
|
out := method.Call(nil)
|
||||||
|
return out[0].Bool(), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, false
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ func NewCLI() *CLI {
|
|||||||
&c.cmd,
|
&c.cmd,
|
||||||
kong.Name("mftecmd"),
|
kong.Name("mftecmd"),
|
||||||
kong.Description("Utility for processing $MFT, $J, $LogFile, $Boot, $SDS, $I30"),
|
kong.Description("Utility for processing $MFT, $J, $LogFile, $Boot, $SDS, $I30"),
|
||||||
kong.UsageOnError(),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
@@ -28,8 +27,24 @@ func NewCLI() *CLI {
|
|||||||
|
|
||||||
// Метод запуска CLI
|
// Метод запуска CLI
|
||||||
func (c *CLI) Run() *CMD {
|
func (c *CLI) Run() *CMD {
|
||||||
|
// Парсинг флагов и аргументов
|
||||||
ctx, err := c.parser.Parse(os.Args[1:])
|
ctx, err := c.parser.Parse(os.Args[1:])
|
||||||
c.parser.FatalIfErrorf(err)
|
if err != nil {
|
||||||
|
c.parser.FatalIfErrorf(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Валидируем команды
|
||||||
|
err = ValidateLeaf(c)
|
||||||
|
if err != nil {
|
||||||
|
c.parser.FatalIfErrorf(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Валидируем путь вывода
|
||||||
|
err = ValidateOutput(c)
|
||||||
|
if err != nil {
|
||||||
|
c.parser.FatalIfErrorf(err)
|
||||||
|
}
|
||||||
|
|
||||||
_ = ctx
|
_ = ctx
|
||||||
|
|
||||||
return &c.cmd
|
return &c.cmd
|
||||||
|
|||||||
0
internal/processing/mft/extract.go
Normal file
0
internal/processing/mft/extract.go
Normal file
1
internal/processing/mft/parse.go
Normal file
1
internal/processing/mft/parse.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package mft
|
||||||
0
internal/processing/mft/show.go
Normal file
0
internal/processing/mft/show.go
Normal file
Reference in New Issue
Block a user