-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Autoload of striped images #95
base: master
Are you sure you want to change the base?
Changes from all commits
79d4d3e
9e057c8
987bcf5
4c4a4c5
b971e29
4d37cdf
3851234
10eef8f
008bf27
6a66a8b
1dc699f
aaeae31
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
BUILDING MacOS | ||
================ | ||
|
||
Install the following via brew | ||
|
||
brew install snappy lz4 raptor pkgconfig tclap uriparser spdlog | ||
|
||
Then do the following | ||
|
||
cd ~/git | ||
git clone https://github.com/gabime/spdlog.git | ||
cd spdlog | ||
git checkout v0.17.0 | ||
cmake . && make all install | ||
cd .. | ||
git clone https://github.com/Velocidex/c-aff4.git | ||
cd c-aff4 | ||
git submodule update --init third_party/gtest | ||
|
||
Ignore the error about tree reference. | ||
|
||
cd third_party/gtest | ||
git reset --hard | ||
cd ../.. | ||
./autogen.sh | ||
./configure CC=clang CXX=clang++ CXXFLAGS="-std=c++11 -stdlib=libc++ -O2 -g0 -I/opt/local/include" LDFLAGS="-stdlib=libc++ -L/opt/local/lib" | ||
make | ||
|
||
For the manual installations, need to ensure they are installed in /opt/local. ("./configure --prefix=/opt/local") |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,7 +47,7 @@ class FileBackedObject: public AFF4Stream { | |
// The filename for this object. | ||
std::string filename; | ||
|
||
explicit FileBackedObject(DataStore* resolver): AFF4Stream(resolver), fd(0){} | ||
explicit FileBackedObject(DataStore* resolver, std::string filename): AFF4Stream(resolver), filename(filename), fd(0){} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is unnecessary as we have a factory function below. You should never need to create an instance of this type without a unique ptr to manage it. |
||
virtual ~FileBackedObject(); | ||
|
||
AFF4Status ReadBuffer(char* data, size_t *length) override; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -248,7 +248,8 @@ AFF4Status BasicImager::handle_aff4_volumes() { | |
AFF4Flusher<AFF4Stream>(backing_stream.release()), | ||
volume)); | ||
|
||
volume_objs.AddVolume(AFF4Flusher<AFF4Volume>(volume.release())); | ||
volume_objs.AddVolume(std::move(AFF4Flusher<AFF4Volume>(volume.release()))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the std::move from this call, it's not needed and will stop automatic copy elision |
||
volume_objs.AddSearchPath(volume_to_load); | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,8 +99,20 @@ AFF4Status AFF4Map::OpenAFF4Map( | |
line.erase(line.length()-1, 1); | ||
} | ||
AFF4Flusher<AFF4Stream> target; | ||
RETURN_IF_ERROR(volumes->GetStream(URN(line), target)); | ||
|
||
if((volumes->GetStream(URN(line), target)) != STATUS_OK){ | ||
// Search in the repository for this target. | ||
resolver->logger->info("Attempting to locate resource {} ", line); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually do not think this is a good architectural choice - we are breaking down the encapsulation between classes and assuming a particular context. This makes the code more fragile. I think it is a mistake to lump volume discovery together with the volume group - volume groups are there to manager lifetimes and they currently do not assume a particular volume implementation (like zip files stored in file backed objects). It is the imager which is aware of the details and it should do the right thing. IMHO the way this should work is - you try to open the map at which point the map object checks that all the named targets are valid. If any are not known it should return an error status to that effect. The imager should then handle the error if it wants and it makes sense by scanning the volumes near the one we started with. Remember that sometimes the volume may not even be stored on a filesystem and it does not make any sense to try to open it here. |
||
if(resolver->HasURNWithAttribute(URN(line), AFF4_STORED)){ | ||
// Get the ID of the container with this stream. | ||
URN targetContainer; | ||
RETURN_IF_ERROR(resolver->Get(URN(line), AFF4_STORED, targetContainer)); | ||
RETURN_IF_ERROR(volumes->LocateAndAdd(targetContainer)); | ||
RETURN_IF_ERROR(volumes->GetStream(URN(line), target)); | ||
} else { | ||
return NOT_FOUND; | ||
} | ||
} | ||
|
||
resolver->logger->debug("MAP: Opened {} {} for target {}", | ||
target->urn, line, map_obj->targets.size()); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ Unless required by applicable law or agreed to in writing, software distributed | |
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations under the License. | ||
*/ | ||
*/ | ||
|
||
#ifndef SRC_AFF4_UTILS_H_ | ||
#define SRC_AFF4_UTILS_H_ | ||
|
@@ -22,19 +22,22 @@ specific language governing permissions and limitations under the License. | |
#include <string> | ||
#include <sstream> | ||
|
||
#include <codecvt> | ||
#include <locale> | ||
|
||
#include "spdlog/spdlog.h" | ||
|
||
namespace aff4 { | ||
|
||
#define UNUSED(x) (void)x | ||
|
||
std::string aff4_sprintf(std::string fmt, ...); | ||
std::string aff4_sprintf(std::string fmt, ...); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please indent this and below back. A namespace definition does not increase indentation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you want me to de-indent all of your code too? All the existing code is at a 4 space indent. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://google.github.io/styleguide/cppguide.html#Namespace_Formatting The contents of namespaces are not indented. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My mistake. Apologies for the unwarranted whitespace change. |
||
|
||
std::string GetLastErrorMessage(); | ||
std::string GetLastErrorMessage(); | ||
|
||
std::vector<std::string> split(const std::string& s, char delim); | ||
std::vector<std::string> split(const std::string& s, char delim); | ||
|
||
std::shared_ptr<spdlog::logger> get_logger(); | ||
std::shared_ptr<spdlog::logger> get_logger(); | ||
|
||
#define RETURN_IF_ERROR(expr) \ | ||
do { \ | ||
|
@@ -45,19 +48,62 @@ std::shared_ptr<spdlog::logger> get_logger(); | |
}; \ | ||
} while (0); | ||
|
||
// A portable version of fnmatch. | ||
int fnmatch(const char *pattern, const char *string); | ||
// A portable version of fnmatch. | ||
int fnmatch(const char *pattern, const char *string); | ||
|
||
inline bool hasEnding(std::string const &fullString, std::string const &ending) { | ||
if (fullString.length() >= ending.length()) { | ||
return (0 == fullString.compare( | ||
inline bool hasEnding(std::string const &fullString, std::string const &ending) { | ||
if (fullString.length() >= ending.length()) { | ||
return (0 == fullString.compare( | ||
fullString.length() - ending.length(), | ||
ending.length(), ending)); | ||
} else { | ||
return false; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
inline bool IsAFF4Container(std::string filename) noexcept { | ||
// Cheap nasty not really unicode transformation to lower case. | ||
std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower); | ||
return hasEnding(filename, ".af4") || hasEnding(filename, ".aff4"); | ||
} | ||
|
||
/** | ||
* Does the file entity exist, and is a regular file. | ||
* @param name The filename to check | ||
* @return TRUE if the file entity exists and is a regular file. | ||
*/ | ||
inline bool IsFile(const std::string& name) { | ||
#ifndef _WIN32 | ||
/* | ||
* POSIX based systems. | ||
*/ | ||
struct stat buffer; | ||
if (::stat(name.c_str(), &buffer) == 0) { | ||
return S_ISREG(buffer.st_mode); | ||
} | ||
return false; | ||
#else | ||
/* | ||
* Windows based systems | ||
*/ | ||
std::wstring filename = s2ws(name); | ||
DWORD dwAttrib = GetFileAttributes(filename.c_str()); | ||
return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); | ||
|
||
#endif | ||
} | ||
|
||
inline std::wstring s2ws(const std::string& str) { | ||
using convert_typeX = std::codecvt_utf8<wchar_t>; | ||
std::wstring_convert<convert_typeX, wchar_t> converterX; | ||
return converterX.from_bytes(str); | ||
} | ||
} | ||
|
||
inline std::string ws2s(const std::wstring& wstr) { | ||
using convert_typeX = std::codecvt_utf8<wchar_t>; | ||
std::wstring_convert<convert_typeX, wchar_t> converterX; | ||
return converterX.to_bytes(wstr); | ||
} | ||
|
||
} // namespace aff4 | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -153,6 +153,7 @@ AFF4_Handle* AFF4_open(const char* filename, AFF4_Message** msg) { | |
}; | ||
|
||
h->volumes.AddVolume(std::move(zip)); | ||
h->volumes.AddSearchPath(filename); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. search path is not related to the volume group (volumes have no concept of paths). This should be a separate helper object or function. |
||
|
||
// Attempt AFF4 Standard, and if not, fallback to AFF4 Evimetry Legacy format. | ||
images = h->resolver.Query(aff4::AFF4_TYPE, &type); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just use the factory function