| |
| Posted by Denzien | PermalinkReply |
|
Denzien
| Hi everyone, I'm working on a simple application to research the true volatility of RAM in my Digital Forensics class and I've run into a small roadblock.
I've read that I can (possibly) address up to 3/4 of the available system memory using the x32 DOS extender, but my application can only malloc up to about 64MB.
The idea of the program is simple: after booting into a very small footprint OS (DOS), allocate all available memory and fill that memory with identifiable "needles". After rebooting the machine, again run the application to re-allocate the memory and then search for the needles in memory (in lieu of performing a memory dump and using a hard drive). This is designed to be run from a CD for fast results on a variety of machines (Laptop, Desktop, Workstation, different brand names, etc)
The file is named Needler.cpp, and I from its directory I compile
using the following command:
"c:\dm\bin\dmc Needler.cpp -Ae -ml -mx x32.lib"
The following is my simple and un-optimized code that seems to work great in the first 64MB:
/********************************/
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <malloc.h>
#include <x32.h>
#include <dos.h>
#define KB 1024
#define MB (1024 * KB)
void processArguments(int argc, char* argv[]);
void writeMenu();
void hideNeedles(char * buffer);
int FindNeedles();
int ByteToInt(char *data);
void PrintMenu();
char* doMalloc();
int SearchMemory(int offset);
void *_x386_zero_base_ptr;
int plantedNeedles = 0;
int needleLength = 53;
char needle[53]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZzyxwvutsrqponmlkjihgfedcba";
bool verbose = false;
bool read = false;
bool write = false;
int main(int argc, char* argv[])
{
int result;// = SearchMemory();
processArguments(argc, argv);
if (read || write)
{
printf("\nPerforming Operations...\n\n");
result = FindNeedles();
}
else
{
writeMenu();
return 0;
}
if (read) printf("\n\nFound %i needles in the haystack.",
result);
return 0;
}
void processArguments(int argc, char* argv[])
{
char verboseSwitch[3] = "-v";
char readSwitch[3] = "-r";
char writeSwitch[3] = "-w";
for(int i = 0; i < argc; i++)
{
if(argv[i][1] == verboseSwitch[1]) verbose = true;
else if(argv[i][1] == readSwitch[1]) read = true;
else if(argv[i][1] == writeSwitch[1]) write = true;
else if(argv[i][1] == 'o')
{
int x = ByteToInt(argv[++i]);
printf("\nOffset = %i\n\n", x);
//x = SearchMemory(x);
}
}
}
int ByteToInt(char *data)
{
int result = 0;
int i = 0;
while(data[i] != 0)
{
/*for (int i = 0; i < 20; i++)
{*/
if(((int)data[i] >= 0x30) && ((int)data[i] <=
0x39))
{
result *= 10;
switch(data[i])
{
case '1':
result += 1;
break;
case '2':
result += 2;
break;
case '3':
result += 3;
break;
case '4':
result += 4;
break;
case '5':
result += 5;
break;
case '6':
result += 6;
break;
case '7':
result += 7;
break;
case '8':
result += 8;
break;
case '9':
result += 9;
break;
default:
break;
}
}
/*else if(data[i] == 0x0)
return result;*/
i++;
}
return result;
}
void writeMenu()
{
printf("\n\nUsage:\n");
printf(" -w Write needles into memory\n");
printf(" -r Read needles from memory\n");
printf(" -v Verbose output (makes processing very slow)
\n *Must also choose read or write.\n\n");
printf(" If both read and write are specified,\n Needler
will write needles first, then read.\n\n");
}
char* doMalloc()
{
unsigned long Kilobyte = 1024;
char * buffer = (char*) malloc (Kilobyte * 64);
//if (buffer == NULL) buffer = (char*) malloc (KB);
if ((write) && (buffer != NULL)) hideNeedles(buffer);
return buffer;
}
void hideNeedles(char * buffer)
{
char *ptr = &buffer[0];
int index = 0;
int iterations = KB / (needleLength + 1);
for (int i = 0; i < iterations; i++)
{
memcpy(ptr, needle, needleLength);
ptr += (needleLength + 1);
plantedNeedles++;
}
}
int FindNeedles()
{
char *buffer = doMalloc();
char *ptr = &buffer[0];
char *MAX = &buffer[sizeof(buffer)];
printf("Allocating Memory...");
if (verbose) printf("\n");
while (buffer != NULL)
{
if (&buffer[0] < ptr) ptr = &buffer[0];
if (&buffer[sizeof(buffer)] > MAX) MAX = &buffer
[sizeof(buffer)];
//MAX = &buffer[sizeof(buffer)];
if (verbose) printf("\rMALLOC: &%p ", &buffer[0]);
buffer = doMalloc();
}
if (verbose) printf("\n");
printf("Done. ");
if (write) printf("%i needles planted.\n", plantedNeedles);
if (!read) return 0;
printf("\nFinding needles...");
if (verbose) printf("\nNeedles found:\n0");
int found = 0;
while(ptr < MAX)
{
try
{
if(*ptr == needle[0])
{
if (memcmp(ptr, needle,
needleLength) == 0)
{
found++;
if (verbose) printf("\r%
i", found);
ptr += needleLength;
}
else
{
ptr++;
}
}
}
catch(...)
{
printf("\nError detected -- aborting.\n");
break;
}
ptr++;
}
return found;
}
int SearchMemory(int offset)
{
int count = offset;
char *ptr = (char*)_x386_zero_base_ptr + count;
for(int i = 0; i < 100000000; i++)
{
ptr = (char*)_x386_zero_base_ptr + count;
printf("\r%i - (%c)", count, *ptr);
count++;
}
return count;
}
/********************************/
Also, I can't seem to find any information that describes how to use a DOS 32-bit extender to my liking, so I'm still unsure if I'm going about this in the correct way. Any input would be great!
|