-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbtrfrsc.cpp
174 lines (153 loc) · 5.53 KB
/
btrfrsc.cpp
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//! \file btrfrsc.cpp
//! \author Shujian Yang
//!
//! Main function.
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <exception>
#include <stdexcept>
#include <string>
#include <vector>
#include <memory>
#include <unistd.h>
#include <tsk/libtsk.h>
#include <unistd.h>
#include "Basics/Basics.h"
#include "Trees/Trees.h"
#include "Pool/Pool.h"
#include "Utility/Utility.h"
using namespace std;
using namespace btrForensics;
int main(int argc, char *argv[])
{
TSK_OFF_T offsetSector(0);
int option;
vector<string> offsetStr;
vector<TSK_OFF_T> devOffsets;
while((option = getopt(argc, argv, "o:")) != -1){
switch(option){
case 'o':
offsetStr = strSplit(optarg, ",");
for(auto str : offsetStr){
if( (offsetSector = tsk_parse_offset(str.c_str())) == -1){
tsk_error_print(stderr);
exit(1);
}
devOffsets.push_back(offsetSector);
}
break;
case '?':
default:
cerr << "Unkown arguments." << endl;
}
}
if(optind >= argc) {
cerr << "Please provide the image name" << endl;
exit(1);
}
if(devOffsets.size() == 0)
devOffsets.push_back(0);
string img_name(argv[optind]);
TSK_IMG_INFO *img = tsk_img_open(1, &argv[optind], TSK_IMG_TYPE_DETECT, 0);
if(img == NULL){
tsk_error_print(stderr);
cerr << "Cannot open image " << img_name << "." << endl;
exit(1);
}
for(auto &offSec : devOffsets) {
TSK_OFF_T offsetByte(offSec * img->sector_size);
if( offsetByte >= img->size){
cerr << "Offset is too large." << endl;
exit(1);
}
offSec = offsetByte;
}
try {
BtrfsPool btr(img, TSK_LIT_ENDIAN, devOffsets);
SuperBlock *supblk = btr.primarySupblk;
cout << *supblk << endl;
cout << "Magic: " << supblk->printMagic() << endl;
cout << supblk->printSpace() << endl;
cout << endl;
cout << "Label: " << supblk->printLabel() << endl;
cout << "\n" << endl;
string answer;
while(true) {
cout << "MAIN MENU -- What do you want to do?" << endl;
cout << "[1] Browse nodes derived from root tree and print information." << endl;
cout << "[2] Browse nodes in chunk tree and print information." << endl;
cout << "[3] Browse nodes in filesystem tree and print information." << endl;
cout << "[4] List all files in default filesystem tree." << endl;
cout << "[5] Explor files and subdirectories in default root directory." << endl;
cout << "[6] Switch to a subvolume or snapshot and explore files within." << endl;
cout << "[7] Read a file from image and save to current directory." << endl;
cout << "[q] Quit." << endl;
cout << "Enter your choice > ";
cin >> answer;
cout << endl;
if(answer == "q") break;
cout << std::string(60, '=') << "\n";
cout << endl;
if(answer == "1"){
btr.navigateNodes(btr.rootTree, cout, cin);
}
else if(answer == "2"){
btr.navigateNodes(btr.chunkTree->chunkRoot, cout, cin);
}
else if(answer == "3"){
btr.navigateNodes(btr.fsTreeDefault->fileTreeRoot, cout, cin);
}
else if(answer == "4") {
cout << "Listing directory items...\n" << endl;
uint64_t targetId(btr.fsTree->rootDirId);
btr.fsTree->listDirItemsById(targetId, true, true, true, 0, cout);
cout << endl;
}
else if(answer == "5") {
btr.fsTree->explorFiles(cout, cin);
}
else if(answer == "6") {
if(btr.switchFsTrees(cout, cin)) {
btr.fsTree->explorFiles(cout, cin);
delete btr.fsTree;
btr.fsTree = btr.fsTreeDefault;
}
}
else if(answer == "7") {
cout << "Please enter the inode number of file." << endl;
cout << "(Enter 'q' to quit.)" << endl;
string input;
uint64_t targetId;
bool success(false);
while(true) {
cin >> input;
if(input == "q") break;
if(stringstream(input) >> targetId) {
success = btr.fsTree->readFile(targetId);
break;
}
else {
cin.clear();
cout << "Invalid input. Please try again.\n" << endl;
}
}
if(success)
cout << "Success: File written to current directory." << endl;
else
cout << "Error: File not found or has no content." << endl;
}
else
cout << "Invalid option. Please choose again." << endl;
cout << endl;
}
} catch(std::bad_alloc& ba) {
cerr << "Error when allocating objects.\n" << ba.what() << endl;
} catch(FsDamagedException& fsEx) {
cerr << "Error: Btrfs filesystem damaged.\n" << fsEx.what() << endl;
} catch(exception& e) {
cerr << e.what() << endl;
}
return 0;
}