Join Us!

EnScript 6 or 8, ge...
 
Notifications
Clear all

EnScript 6 or 8, get EntryClass from Physical Sector  

  RSS
JSharpe
(@jsharpe)
New Member

Hello,

I'm currently working on a script that would get the "EntryClass" object of a file given the a ulong physical sector location.

An example of the function signature would look like


EntryClass GetEntry(DeviceClass device, ulong physicalSectorLocation) {
EntryClass foundFile;

// Get the foundFile given the supplied physical sector location.

return foundFile;
}

Does anyone have any experience or suggestions in how to accomplish this?

The end goal is be able to supply a list of physical sector locations then bookmark them. Although the "BookmarkFolderClass" only allows for an "EntryClass" to be supplied in the following methods

AddBookmark()
AddFoldermark()
AddTranscriptmark()

The manual approach would be to open the evidence within Disk View (View Clusters unticked), right click and "Go To…" the physical sector to locate the file, then bookmarking it.

As the title says, I'm trying to get this working in either EnScript 6 or 8; there is no preference.

Any help would be greatly appreciated!

Quote
Posted : 23/04/2019 8:07 am
sdckey
(@sdckey)
New Member

Use DeviceClassGetEntry().

Note the comments at the top of the code.


/*
* This script demonstrates resolution of one or more sectors on the currently highlighted
* physical device.
*
* Note that resolving a sector to an entry is not always straightforward.
*
* Files that are hard-linked, resident, or compressed all add a degree of complication.
*
* Developed using EnCase 8.08.00.140.
*
* Report bugs to
*
* Simon Key <[email protected]>
* Snr. Curriculum Developer - Learning Services (EnCase)
* Reading Office, UK
*
* 25th April 2019
*/

#ifndef ULongArray
typedef ulong[] ULongArray;
#endif

class MainClass;

class MyDialogClass DialogClass
{
MainClass M;

StringEditClass _SectorLocationsAsStrings;

MyDialogClass(MainClass m)
super(null, StringFormat("{0} - {1}", m.ScriptName, m.Device.Name())),
M = m,
_SectorLocationsAsStrings(this, "Sector numbers (one per line)",
START, START, 300, 50,
0,
M.SectorLocationsAsStrings,
-1,
REQUIRED)
{

}

virtual void CheckControls()
{
EnableClose(_SectorLocationsAsStrings.GetText());
superCheckControls();
}

virtual bool CanClose()
{
bool retval = superCanClose();
if (retval)
{
if (!GetSectorLocations())
{
ErrorMessage("Can't get list of valid sector locations.");
retval = false;
}
}
return retval;
}

bool GetSectorLocations()
{
bool retval;
if (String text = _SectorLocationsAsStrings.GetText())
{
NameListClass lines();
lines.Parse(text, "\n");
M.SectorLocations = new ULongArray(0, lines.Count());
String t;
bool success;
ulong sector_location;
foreach (NameListClass line in lines)
{
t = line.Name();
t.Trim(" ", TRIMSTART | TRIMEND);
if (t)
{
sector_location = ulongConvert(t, intDECIMAL, success);
if (success)
{
M.SectorLocations.Add(sector_location);
}
}
}
if (M.SectorLocations.Count())
{
M.SectorLocations.Sort(SORTENABLED | SORTNODUPE);
retval = M.SectorLocations.Count();
}
}
return retval;
}
}

class MainClass {

String ScriptName,
SectorLocationsAsStrings;

DeviceClass Device;

ULongArray SectorLocations;

BookmarkClass Folder;

MainClass()
ScriptName("Bookmark Device Sectors")
{

}

void Main(CaseClass c) {
SystemClassClearConsole(1);
if (c)
{
long offset, size;
if (EntryClass e = EntryClassTypeCast(c.GetCurrentItem(offset, size)))
{
if ((Device = e.GetDevice()) && Device.IsPhysical())
{
Console.WriteLine("Processing device '{0}'.", Device.Name());
AccessStorage();
MyDialogClass dialog(this);
if (dialog.Execute() == SystemClassOK)
{
AccessStorage(StorageClassWRITE);
Folder = new BookmarkClass(c.BookmarkRoot(),
"Bookmarked Sectors",
NodeClassFOLDER);
Console.WriteLine("Sorted list of sector locations");
foreach (ulong sector_location in SectorLocations)
{
Console.WriteLine("\t{0}", sector_location);
}
foreach (ulong sector_location in SectorLocations)
{
Bookmark(sector_location);
}
}
else
{
Console.WriteLine("Cancelled.");
}
}
else
{
Console.WriteLine("Can't get physical device.");
}
}
else
{
Console.WriteLine("Can't get current entry.");
}
}
}

void AccessStorage(uint options = 0)
{
StorageClass storage(ScriptName, options);
storage.Value("SectorLocationsAsStrings", SectorLocationsAsStrings);
}

void Bookmark(ulong sector_location)
{
ulong file_offset;
if (EntryClass e = Device.GetEntry(sector_location * Device.BytesPerSector(),
file_offset))
{
Console.WriteLine("Sector {0} resolves to offset {1} in '{2}'",
sector_location,
file_offset,
e.ItemPath());
BookmarkDecodeClass dec(Folder);
dec.CopyItemData(e);
dec.SetDataOffset(file_offset);
dec.SetDataSize(1);
dec.SetComment(StringFormat("Sector {0}", sector_location));
}
else
{
Console.WriteLine("Can't get entry for sector {0}.", sector_location);
}
}
}

ReplyQuote
Posted : 25/04/2019 10:42 am
JSharpe
(@jsharpe)
New Member

Use DeviceClassGetEntry().

Note the comments at the top of the code.


ulong file_offset;
if (EntryClass e = Device.GetEntry(sector_location * Device.BytesPerSector(),
file_offset))
{
Console.WriteLine("Sector {0} resolves to offset {1} in '{2}'",
sector_location,
file_offset,
e.ItemPath());

This is the knowledge I was missing!
I managed to bookmark the items which were live, however I was only able to bookmark from offset 0; an issue with unallocated, compound files, etc.

I wasn't aware that the 2nd argument passed to "GetEntry (ulong deviceOffset, ulong &fileOffset)" would be modified to contain the offset, although maybe I should have given that it's passed by reference.
I guess this is how EnScript handles returning multiple values from a method/function.

Made a simple wrapper class for future reference when dealing with this


class EntryClassWithOffset
{
EntryClass file_entry;
ulong data_offset;
}

Then using

EntryClassWithOffset GetEntry(DeviceClass device, ulong physicalOffset)
{
EntryClassWithOffset item = new EntryClassWithOffset();

//sector being the physical sector calculated with physical sector location and DeviceClass.Bytes.PerSector()

item.file_entry = device.GetEntry(sector, item.data_offset);

return item;
}

Which is easier to handle the self contained object

// Where "c" is current CaseClass, "d" is current DeviceClass, "physicalSector" is ulongConvert from text array.
BookmarkClass folder (c.BookmarkRoot(), "Physical Sectors", NodeClassFOLDER);
EntryClassWithOffset item = GetEntry(d, physicalSector)
folder.AddBookmark(item.file_entry, item.data_offset, 16, "PS " + physicalSector, 0, BookmarkClassPICTURE);

Thanks to your help I managed to get it working within EnCase v6 as well.

By the way what other documentation is there for the language?
I can only find the in internal "Class Browser" and "EnScript Help 8.07.chm", which aren't the best formatted.
Are there any alternative IDEs available too? I'm mostly doing all the scripting within VS Code right now.

Thanks for the help Simon!

ReplyQuote
Posted : 26/04/2019 8:01 am
sdckey
(@sdckey)
New Member

By the way what other documentation is there for the language?
I can only find the in internal "Class Browser" and "EnScript Help 8.07.chm", which aren't the best formatted.
Are there any alternative IDEs available too? I'm mostly doing all the scripting within VS Code right now.

Thanks for the help Simon!

There is an EnScript language reference. You can find a link on my EnScript GitHub repository

https://github.com/sdckey/EnScript-Samples

It only references the core language syntax - there's no all-encompassing language reference that I know of. EnScript is a niche language, so it doesn't have the support of Java, C++, C#, etc.

I can normally work-out what I need to do using the EnScript language reference, which is tied to the compiler. There may also be some useful examples in the EnScript help file, although that's not tied to the compiler and may not always be up-to-date.

If you or anyone else gets stuck, by all means post a question here, on my Github, or on the OT MySupport EnScript forum. I'll do my best to help.

I only write EnScript in EnCase itself. I don't know of any other GUI.

ReplyQuote
Posted : 26/04/2019 9:23 am
Share: