-
Notifications
You must be signed in to change notification settings - Fork 48
/
researchcommands.go
146 lines (127 loc) · 3.42 KB
/
researchcommands.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// 22 october 2015
package main
import (
"fmt"
"io"
"bytes"
"crypto/aes"
"github.com/andlabs/reallymine/command"
"github.com/andlabs/reallymine/disk"
"github.com/andlabs/reallymine/bridge"
"github.com/andlabs/reallymine/kek"
"github.com/andlabs/reallymine/decryptloop"
)
var zeroSector [disk.SectorSize]byte
func cDumpLast(d *disk.Disk, out io.Writer) error {
var sector []byte
pos := d.Size()
iter, err := d.ReverseIter(pos)
if err != nil {
return err
}
found := false
for iter.Next() {
sector = iter.Sectors()
pos = iter.Pos()
if !bytes.Equal(sector, zeroSector[:]) {
found = true
break
}
}
if err = iter.Err(); err != nil {
return err
}
if !found {
return fmt.Errorf("non-empty sector not found")
}
fmt.Printf("sector at 0x%X\n", pos)
_, err = out.Write(sector)
return err
}
var dumplast = &command.Command{
Name: "dumplast",
Args: []command.Arg{command.ArgDisk, command.ArgOutFile},
Description: "Dumps the last non-zero sector on %s to %s.",
Do: cDumpLast,
}
func cDecryptKeySector(d *disk.Disk, out io.Writer, a *kek.Asker) error {
dec := &Decrypter{
Disk: d,
Out: out,
}
err := dec.FindKeySector()
if err != nil {
return err
}
sector := dec.EncryptedKeySector
if a != nil {
err = dec.ExtractDEK(a)
// ignore bridge.ErrWrongKEK; this command should still produce a dump even in the face of the wrong KEK (with -askonce, -default, or a specific KEK)
if err != nil && err != bridge.ErrWrongKEK {
return err
}
sector = dec.KeySector.Raw()
}
fmt.Printf("%s\n%s\n",
formatSectorPos(dec.KeySectorPos),
formatBridge(dec.Bridge))
_, err = out.Write(sector)
return err
}
func cDumpKeySector(d *disk.Disk, out io.Writer) error {
return cDecryptKeySector(d, out, nil)
}
var dumpkeysector = &command.Command{
Name: "dumpkeysector",
Args: []command.Arg{command.ArgDisk, command.ArgOutFile},
Description: "Identifies and dumps the key sector on %s to %s.",
Do: cDumpKeySector,
}
var decryptkeysector = &command.Command{
Name: "decryptkeysector",
Args: []command.Arg{command.ArgDisk, command.ArgOutFile, command.ArgKEK},
Description: "Identifies, decrypts, and dumps the key sector on %s to %s using %s.",
Do: cDecryptKeySector,
}
const firstSectorsCount = 64
func cDumpFirst(d *disk.Disk, out io.Writer) error {
iter, err := d.Iter(0, firstSectorsCount)
if err != nil {
return err
}
if !iter.Next() {
// if iter.Err() == nil, d.Size() == 0, so just treat it as success
return iter.Err()
}
_, err = out.Write(iter.Sectors())
return err
}
var dumpfirst = &command.Command{
Name: "dumpfirst",
Args: []command.Arg{command.ArgDisk, command.ArgOutFile},
Description: "Dumps the first " +
fmt.Sprintf("%d sectors (%d bytes)", firstSectorsCount, firstSectorsCount * disk.SectorSize) +
" on %s to %s without decrypting.",
Do: cDumpFirst,
}
func cDecryptFile(in io.Reader, out io.Writer, dek []byte, steps decryptloop.StepList) error {
cipher, err := aes.NewCipher(dek)
if err != nil {
return err
}
dl := decryptloop.New(steps, cipher, out)
_, err = io.Copy(dl, in)
if err != nil {
return err
}
if dl.StillPendingData() {
return fmt.Errorf("input file does not end with a complete block")
}
return nil
}
var decryptfile = &command.Command{
Name: "decryptfile",
Args: []command.Arg{command.ArgInFile, command.ArgOutFile, command.ArgDEK, command.ArgDecryptionSteps},
Description: "Decrypts %s to %s using the provided %s and %s.",
Do: cDecryptFile,
}