Skip to content

Commit

Permalink
initial working revision
Browse files Browse the repository at this point in the history
  • Loading branch information
candicenonsense committed May 30, 2015
0 parents commit 843702d
Show file tree
Hide file tree
Showing 6 changed files with 311 additions and 0 deletions.
Empty file added LICENSE
Empty file.
Empty file added README
Empty file.
66 changes: 66 additions & 0 deletions error.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* error.c: Generic error/debug routines
* author: Vassil Roussev
*/

#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "util.h"


/**
* Allocate memory, check result, and print error (if necessary).
*/
void *alloc_check( uint32_t alloc_type, uint64_t mem_bytes, const char *fun_name, const char *var_name, uint32_t error_action) {
void *mem_chunk = NULL;

switch( alloc_type) {
case ALLOC_ONLY:
mem_chunk = malloc( mem_bytes);
break;
case ALLOC_AUTO:
mem_chunk = malloc( mem_bytes);
break;
case ALLOC_ZERO:
mem_chunk = calloc( 1, mem_bytes);
break;
default:
return NULL;
}
if( mem_chunk == NULL) {
fprintf( stderr, "Could not allocate %dKB (%dMB) for %s in function %s(). System message: \"%s\".",
(int)(mem_bytes >> 10), (int)(mem_bytes >> 20), var_name, fun_name, strerror( errno));
if( error_action == ERROR_EXIT) {
fprintf( stderr, " Exiting.\n");
exit(-1);
}
}
return mem_chunk;
}
void *realloc_check( void *buffer, uint64_t new_size) {
void *mem_chunk = realloc( buffer, new_size);

return mem_chunk;
}

/**
* Print a 256-byte buffer
*/
void print256( const uint8_t *buffer) {
uint16_t i;
fprintf( stderr, " ");
for( i=0; i<32; i++)
fprintf( stderr, "%02x ", i);
fprintf( stderr, "\n");

for( i=0; i<256; i++) {
if( i % 32 == 0)
fprintf( stderr, "%04x: ", i);
fprintf( stderr, "%02x ", buffer[i]);
if( i % 32 == 31)
fprintf( stderr, "\n");
}
}
43 changes: 43 additions & 0 deletions map_file.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fstream>

#include "util.h"

using namespace std;

/**
* Open & read in a file (compile w/ -D_FILE_OFFSET_BITS=64)
*/
processed_file_t *process_file(const char *fname) {
processed_file_t *mfile = (processed_file_t *) alloc_check( ALLOC_ZERO, sizeof( processed_file_t), "map_file", "mfile", ERROR_EXIT);
struct stat file_stat;
ifstream *is= new ifstream();

if( stat( fname, &file_stat)) {
fprintf( stderr, "Warning: Could not stat file '%s'. Skipping.\n", fname);
return NULL;
}
is->open(fname,ios::binary);

mfile->buffer = (uint8_t*)alloc_check(ALLOC_ZERO,sizeof(uint8_t)*file_stat.st_size, "read_file", "mfile", ERROR_EXIT);
is->read((char*)mfile->buffer,file_stat.st_size);
int res=is->gcount();
if( res != file_stat.st_size) {
fprintf( stderr, "read failed: %s.\n", strerror( errno));
free( mfile);
is->close();
return NULL;
}
mfile->name = (char*)fname;
mfile->size = file_stat.st_size;
is->close();
return mfile;
}

166 changes: 166 additions & 0 deletions nullfinder.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@

/** File: nullfinder.cc
Author: Candice Quates
Program: gpunullfinder
Takes argument of a file of dumped gpu memory, attempts to divine structure
by searching for blocks of nulls which have been added for padding.
Default block of nulls to search for is 8. extracting is only for 8-null blocks.
File parsing code lifted from sdhash, apache license (Roussev/Quates 2013)
General structure and command line arguments lifted from zsniff. (apache license)
*/

/* compile with:
g++ -std=c++0x -o nullf nullfinder.cc map_file.cc error.cc
*/


#include <vector>
#include <cstddef>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>



#define VERSION "nullfind 0.1 by Candice Quates May 2015"

#include "util.h"


int
writeExtracted(std::vector<unsigned char> &image, std::string filename) {
std::string outfilename = filename+".extract";
std::filebuf fb;
fb.open (outfilename.c_str(),std::ios::out|std::ios::binary);
if (fb.is_open()) {
std::ostream os(&fb);
os.write((const char *)image.data(), image.size());
fb.close();
return 0;
} else {
std::cerr << "nullfind: cannot write to " << outfilename << std::endl;
return 1;
}
}

// using null size default to 8 nulls
// option for extract/noextract
// null size changing does not work yet
// other desired feature: use stringbuilder to make pretty hex address filenames
int
main(int argc, char *argv[])
{
bool extract = false;
if (argc < 2 ) {
std::cout << VERSION << std::endl << std::endl;
std::cout << "Usage: "<< argv[0] << " [--extract] [--nulls 8] filename(s) " << std::endl;
return 1;
}
bool nullsm=false;
int nullssize=8;
// look for extract and nulls size
for (int i=0; i<argc; i++) {
if (std::string("--extract").compare(std::string(argv[i]))==0) {
extract=true;
}
if (nullsm==true) {
if (isdigit(argv[i][0])) {
nullssize=atoi(argv[i]);
} else {
std::cerr << "usage: "<< argv[0] << " [--extract] [--nulls 8] filename(s) " << std::endl;
return 1;
}
nullsm=false;
}
if (std::string("--nulls").compare(std::string(argv[i]))==0) {
nullsm=true;
}
}
std::cout <<"null size "<< nullssize << std::endl;
nullsm=false;
//loop for multiple files here
for (int i=1; i<argc; i++) {
if (std::string("--extract").compare(std::string(argv[i]))==0) {
continue;
}
// nulls marker to ignore argument after --block
if (nullsm==true) {
nullsm=false;
continue;
}
if (std::string("--nulls").compare(std::string(argv[i]))==0) {
nullsm=true;
continue;
}
const char* filename = argv[i] ;

//load files -- the sdhash methods reliably parse files with nulls
processed_file_t *mfile=process_file(filename);
if (mfile->size == 0) {
std::cerr << "nullf: file " << filename << " empty or not found" << std::endl;
return 1;
}
int error=0;
std::cout << "nullf processing: "<< filename << std::endl;
uint8_t current=0;
// There is some integer size mismatching to be fixed here.
int range=0;
int nullcount=0;
int startaddr=0;
// I am well aware that there are prettier and more
// elegant ways to do this, but this is much faster
// than I expected it to be (ie, a few minutes on a VM for 2gb file)
for (int n=0; n < mfile->size ; n++) {
current=(uint8_t)*(mfile->buffer+n);
if (n==0 && current != 0)
std::cout<< std::hex <<n <<" data begin ";
if (current == 0) {
nullcount++;
if (range != 1 && nullcount == 8) {
std::cout<< std::hex <<n <<" ends" << std::endl;
std::cout<< std::hex <<n-8 <<" nulls begin " ;
// extract data
if (extract) {
std::vector<unsigned char> image;
image.resize(n-7-startaddr);
for (int x=0,y=startaddr; y<n-7; x++,y++) {
image[x]=(unsigned char)*(mfile->buffer+y);
}
writeExtracted(image,std::string(filename)+std::to_string((int)startaddr));
}
range=1;
startaddr=0;
}
} else {
// if we've changed state, note that.
if (range == 1) {
std::cout<< std::hex <<n <<" end "<< std::endl;
std::cout<< std::hex <<n <<" data begin ";
startaddr=n;
}
range=0;
nullcount = 0;
}
}
// If we've reached EOF and are in a block of data,
// extract if asked.
if (nullcount==0) {
std::cout<< std::hex <<n<<" ends" << std::endl;
if (extract) {
std::vector<unsigned char> image;
image.resize(n-7-startaddr);
for (int x=0,y=startaddr; y<n-7; x++,y++) {
image[x]=(unsigned char)*(mfile->buffer+y);
}
writeExtracted(image,std::string(filename)+std::to_string((int)startaddr));
}
}
} // loop for parsing multiple files
return 0;
}



36 changes: 36 additions & 0 deletions util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* General definitions (Vassil Roussev)
*/
#ifndef __UTIL_H
#define __UTIL_H

#include <stdio.h>
#include <stdint.h>

#define KB 1024
#define MB (KB*KB)
#define GB (MB*KB)

#define ALLOC_ONLY 1
#define ALLOC_ZERO 2
#define ALLOC_AUTO 3

#define ERROR_IGNORE 0
#define ERROR_EXIT 1

// Struct describing a mapped file
typedef struct {
char *name;
int fd;
FILE *input;
uint64_t size;
uint8_t *buffer;
} processed_file_t;

processed_file_t *process_file(const char *fname);

void print256( const uint8_t *buffer);
void *alloc_check( uint32_t alloc_type, uint64_t mem_bytes, const char *fun_name, const char *var_name, uint32_t error_action);
void *realloc_check( void *buffer, uint64_t new_size);

#endif

0 comments on commit 843702d

Please sign in to comment.