±Forensic Focus Partners

Become an advertising partner

±Your Account


Username
Password

Forgotten password/username?

Site Members:

New Today: 0 Overall: 35503
New Yesterday: 0 Visitors: 138

±Follow Forensic Focus

Forensic Focus Facebook PageForensic Focus on TwitterForensic Focus LinkedIn GroupForensic Focus YouTube Channel

RSS feeds: News Forums Articles

±Latest Articles

±Latest Webinars

EnScript 6 or 8, get EntryClass from Physical Sector

Forensic software discussion (commercial and open source/freeware). Strictly no advertising.
Reply to topicReply to topic Printer Friendly Page
Forum FAQSearchView unanswered posts
 
  

JSharpe
Newbie
 

EnScript 6 or 8, get EntryClass from Physical Sector

Post Posted: Apr 23, 19 07:07

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:

Code:
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:
Code:
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!  
 
  

sdckey
Newbie
 

Re: EnScript 6 or 8, get EntryClass from Physical Sector

Post Posted: Apr 25, 19 09:42

Use DeviceClass::GetEntry().

Note the comments at the top of the code.

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, String::Format("{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());
    super::CheckControls();
  }

  virtual bool CanClose()
  {
    bool retval = super::CanClose();
    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 = ulong::Convert(t, int::DECIMAL, 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) {
    SystemClass::ClearConsole(1);
    if (c)
    {
      long offset, size;
      if (EntryClass e = EntryClass::TypeCast(c.GetCurrentItem(offset, size)))
      {
        if ((Device = e.GetDevice()) && Device.IsPhysical())
        {
          Console.WriteLine("Processing device '{0}'.", Device.Name());
          AccessStorage();
          MyDialogClass dialog(this);
          if (dialog.Execute() == SystemClass::OK)
          {
            AccessStorage(StorageClass::WRITE);
            Folder = new BookmarkClass(c.BookmarkRoot(), 
                                       "Bookmarked Sectors", 
                                       NodeClass::FOLDER);
            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(String::Format("Sector: {0}", sector_location));
    }
    else
    {
      Console.WriteLine("Can't get entry for sector {0}.", sector_location);
    }
  }
}

 
 
  

JSharpe
Newbie
 

Re: EnScript 6 or 8, get EntryClass from Physical Sector

Post Posted: Apr 26, 19 07:01

- sdckey
Use DeviceClass::GetEntry().

Note the comments at the top of the code.

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:

Code:
class EntryClassWithOffset
{
    EntryClass file_entry;
    ulong data_offset;
}

Then using:
Code:
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:
Code:
// Where "c" is current CaseClass, "d" is current DeviceClass, "physicalSector" is ulong::Convert from text array.
BookmarkClass folder (c.BookmarkRoot(), "Physical Sectors", NodeClass::FOLDER);
EntryClassWithOffset item = GetEntry(d, physicalSector)
folder.AddBookmark(item.file_entry, item.data_offset, 16, "PS: " + physicalSector, 0, BookmarkClass::PICTURE);

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!  
 
  

sdckey
Newbie
 

Re: EnScript 6 or 8, get EntryClass from Physical Sector

Post Posted: Apr 26, 19 08:23

- JSharpe


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:

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.  
 

Page 1 of 1