SlideShare a Scribd company logo
Advanced EnScript Workshop Jon Stewart Sr. Manager, EnScript Services
Workshop Agenda Language Core Concepts Basic APIs Execution environment and debugging Dialogs Handling evidence External automation and communication Conditions and Reflection Multithreading
Language Core Concepts Syntax and Object Model Basics Inheritance NodeClass! NodeClass! NodeClass! Memory Management Arrays Handlers Stewart’s 3 Fundamental Laws of EnScript
Syntax and Object Model C++-ish syntax, object model is more Java Fundamental datatypes have stack storage Strings are 2-byte Unicode (UCS-16)‏ Loops, functions: nothing new Arithmetic operators are the same Few global variables (biggies are Console, and LocalMachine)‏
Object Model All code organized into classes All class members are inherently  public Functions can be static Objects are heap allocated and manipulated through references => reference semantics, not value semantics Objects are constructed, references are assigned “ implicit new” syntax Members initialized in order of declaration (just like C++)
Inheritance Single inheritance only! Not even interface inheritance, like Java Functions can be overridden if  virtual No final – all overrides must be virtual, too Call parent class constructor first Define interfaces using  pure Almost all derived classes inherit from…
NodeClass Composite design pattern Singly-linked list which can contain linked lists Member data: Next, First Child, Last Child All lists and trees have a parent/root node Add children by passing in parent to constructor, or using Insert()‏ foreach()  and  forall()‏ First Fundamental Law of EnScript:  Data structures should almost always be composed from NodeClass
Memory Management Most fundamental datatypes are stack allocated and have value semantics bool, byte, char, short, ushort, int, uint, long, ulong, double, variant, IPClass, HashClass, DateClass Strings are heap allocated, but have value semantics All objects are heap allocated and have reference semantics Like Java, or like pointers in C++ Reference counting is used for memory management Beware of cyclic reference problem; use  weak  to create weak references But don’t leave dangling references!
Memory Management and NodeClass Second Fundamental Law of EnScript:  All simple objects are ref-counted,  but only  root  NodeClass objects are ref-counted.  NodeClass objects in a list or tree  are not ref-counted! Corollary: If the root dies, children die Insert() and Remove() work with reference counting Why? Efficiency, legacy Real easy to hose yourself (and EnCase)
Memory Management and Destruction Objects are deallocated on the thread holding the last reference, at the time the last reference disappears (block close) Predictable; no separate garbage collection thread Runtime holds global list of all references. At exit, will run through list of any remaining references and report leaks. Destructor is called before deallocation, if defined Don’t be stupid in your destructor Don’t reassign  this  to other references Almost all crashes in EnScript are caused by hosing yourself with dangling references
Arrays Arrays are a later addition to the language Must create typedef first Either static-sized or variable-sized GetCount(), SetCount(), Add() Object arrays store references foreach()  works, but a little funky Arrays themselves are ref-counted; root object references within them are ref-counted as well
Handlers Handler: a class that presents a view of another class Most EnCase data objects are exposed to EnScript through handlers Third Fundamental Law of EnScript:  Most of the EnScript classes are auto-generated by handlers from the EnCase views. WYSIWYG. You can create your own handlers for display through dialogs.
Basic APIs CaseClass, EntryClass, BookmarkClass, FileClass, SearchClass, DirectoryClass, ConnectionClass CaseClass has different roots. Access is read-only, to avoid threading concerns. EntryClass: filesystem metadata BookmarkClass: refer to entries FileClass: work with streams SearchClass: search, hash, file sig DirectoryClass: Local OS filesystem access ConnectionClass: Perform commands on a system
Execution Environment Scripts execute on a background thread Objects you create, whether of API classes or your own classes, are not thread-safe Objects provided to you, through CaseClass and GlobalDataClass, are  constant , for thread safety purposes At script termination, new objects of some classes are incorporated into the rest of EnCase (e.g. bookmarks).
Debugging and EnPacks Beginning with v6.8, EnCase has a source-level debugger. To activate, create a new item in the Projects view and choose .EnScript file containing MainClass Step through lines and inspect variables similar to Visual Studio EnScripts can be statically “compiled” into  EnPack  files. Contains all source code dependencies in a single, binary file. Can be optionally tied to an  EnLicense  file, which can contain #define symbols, dongle IDs, and expiration timestamps Create EnPacks by creating a new item in the Packages view. Right-click and choose Build or Create License.
Dialogs Create your own dialogs by inheriting from DialogClass Use widgets as members: CheckBoxClass, IntEditClass, StringEditClass, ListEditClass, TreeEditClass, TreeTableClass, etc. Each widget takes a raw memory reference to a variable Don’t change the variables out from under the widgets Implement virtual functions to receive callback events. Callbacks occur on special display thread, and all manipulation of the widgets should be done through this thread
Handling Evidence CaseClass::AddEvidenceFile() to open up an evidence file, either .E01 or .L01 EvidenceFileClass can be used to make acquisitions LogicalEvidenceFileClass is very versatile and can be used for creating derivative evidence containers, as well as almost any other kind of persistent storage. Evidence cannot be added to open cases in EnCase, but new cases created in the script can be pulled through to EnCase after script termination.
External Automation and Execution Simplest (best): ExecuteClass. Launch command-line applications. Otherwise: COM host. Import COM type libraries into EnScript engine, create objects, manipulate them. Can typically only pass simple, variant-compatible datatypes COM events (i.e. callbacks) are not supported Cannot inherit from COM interface classes Can use ADO for talking to databases through recordsets Avoid if possible; use something more loosely coupled. SocketClass: Synchronous I/O to/from sockets WebClientClass: GET/PUT/POST/DELETE to a web server. Great for interacting with web services.
Conditions and Reflection EnScript can eat its own tail First step: Conditions. Just a GUI for auto-generating code. To execute, you need ProgramClass Can execute as a Filter or as a normal script Conditions and ProgramClass objects require a SymbolClass object SymbolClass objects represent EnScript classes, PropertyClass objects represent class properties Reflection is the most powerful feature in EnScript Must use NodeClass to play with reflection
Multithreading To create your own threads, inherit from ThreadClass and override Run() virtual function. Use the  synchronized  keyword to define critical sections. Global mutex across all threads. For finer-grained synchronization, can use SemaphoreClass… just as much of a pain as you can imagine. Prefer coarse-grained synchronization as much as possible. Multithreading can make a huge difference in the right situations, but use judiciously. Like any other language, don’t share objects between threads.

More Related Content

EnScript Workshop

  • 1. Advanced EnScript Workshop Jon Stewart Sr. Manager, EnScript Services
  • 2. Workshop Agenda Language Core Concepts Basic APIs Execution environment and debugging Dialogs Handling evidence External automation and communication Conditions and Reflection Multithreading
  • 3. Language Core Concepts Syntax and Object Model Basics Inheritance NodeClass! NodeClass! NodeClass! Memory Management Arrays Handlers Stewart’s 3 Fundamental Laws of EnScript
  • 4. Syntax and Object Model C++-ish syntax, object model is more Java Fundamental datatypes have stack storage Strings are 2-byte Unicode (UCS-16)‏ Loops, functions: nothing new Arithmetic operators are the same Few global variables (biggies are Console, and LocalMachine)‏
  • 5. Object Model All code organized into classes All class members are inherently public Functions can be static Objects are heap allocated and manipulated through references => reference semantics, not value semantics Objects are constructed, references are assigned “ implicit new” syntax Members initialized in order of declaration (just like C++)
  • 6. Inheritance Single inheritance only! Not even interface inheritance, like Java Functions can be overridden if virtual No final – all overrides must be virtual, too Call parent class constructor first Define interfaces using pure Almost all derived classes inherit from…
  • 7. NodeClass Composite design pattern Singly-linked list which can contain linked lists Member data: Next, First Child, Last Child All lists and trees have a parent/root node Add children by passing in parent to constructor, or using Insert()‏ foreach() and forall()‏ First Fundamental Law of EnScript: Data structures should almost always be composed from NodeClass
  • 8. Memory Management Most fundamental datatypes are stack allocated and have value semantics bool, byte, char, short, ushort, int, uint, long, ulong, double, variant, IPClass, HashClass, DateClass Strings are heap allocated, but have value semantics All objects are heap allocated and have reference semantics Like Java, or like pointers in C++ Reference counting is used for memory management Beware of cyclic reference problem; use weak to create weak references But don’t leave dangling references!
  • 9. Memory Management and NodeClass Second Fundamental Law of EnScript: All simple objects are ref-counted, but only root NodeClass objects are ref-counted. NodeClass objects in a list or tree are not ref-counted! Corollary: If the root dies, children die Insert() and Remove() work with reference counting Why? Efficiency, legacy Real easy to hose yourself (and EnCase)
  • 10. Memory Management and Destruction Objects are deallocated on the thread holding the last reference, at the time the last reference disappears (block close) Predictable; no separate garbage collection thread Runtime holds global list of all references. At exit, will run through list of any remaining references and report leaks. Destructor is called before deallocation, if defined Don’t be stupid in your destructor Don’t reassign this to other references Almost all crashes in EnScript are caused by hosing yourself with dangling references
  • 11. Arrays Arrays are a later addition to the language Must create typedef first Either static-sized or variable-sized GetCount(), SetCount(), Add() Object arrays store references foreach() works, but a little funky Arrays themselves are ref-counted; root object references within them are ref-counted as well
  • 12. Handlers Handler: a class that presents a view of another class Most EnCase data objects are exposed to EnScript through handlers Third Fundamental Law of EnScript: Most of the EnScript classes are auto-generated by handlers from the EnCase views. WYSIWYG. You can create your own handlers for display through dialogs.
  • 13. Basic APIs CaseClass, EntryClass, BookmarkClass, FileClass, SearchClass, DirectoryClass, ConnectionClass CaseClass has different roots. Access is read-only, to avoid threading concerns. EntryClass: filesystem metadata BookmarkClass: refer to entries FileClass: work with streams SearchClass: search, hash, file sig DirectoryClass: Local OS filesystem access ConnectionClass: Perform commands on a system
  • 14. Execution Environment Scripts execute on a background thread Objects you create, whether of API classes or your own classes, are not thread-safe Objects provided to you, through CaseClass and GlobalDataClass, are constant , for thread safety purposes At script termination, new objects of some classes are incorporated into the rest of EnCase (e.g. bookmarks).
  • 15. Debugging and EnPacks Beginning with v6.8, EnCase has a source-level debugger. To activate, create a new item in the Projects view and choose .EnScript file containing MainClass Step through lines and inspect variables similar to Visual Studio EnScripts can be statically “compiled” into EnPack files. Contains all source code dependencies in a single, binary file. Can be optionally tied to an EnLicense file, which can contain #define symbols, dongle IDs, and expiration timestamps Create EnPacks by creating a new item in the Packages view. Right-click and choose Build or Create License.
  • 16. Dialogs Create your own dialogs by inheriting from DialogClass Use widgets as members: CheckBoxClass, IntEditClass, StringEditClass, ListEditClass, TreeEditClass, TreeTableClass, etc. Each widget takes a raw memory reference to a variable Don’t change the variables out from under the widgets Implement virtual functions to receive callback events. Callbacks occur on special display thread, and all manipulation of the widgets should be done through this thread
  • 17. Handling Evidence CaseClass::AddEvidenceFile() to open up an evidence file, either .E01 or .L01 EvidenceFileClass can be used to make acquisitions LogicalEvidenceFileClass is very versatile and can be used for creating derivative evidence containers, as well as almost any other kind of persistent storage. Evidence cannot be added to open cases in EnCase, but new cases created in the script can be pulled through to EnCase after script termination.
  • 18. External Automation and Execution Simplest (best): ExecuteClass. Launch command-line applications. Otherwise: COM host. Import COM type libraries into EnScript engine, create objects, manipulate them. Can typically only pass simple, variant-compatible datatypes COM events (i.e. callbacks) are not supported Cannot inherit from COM interface classes Can use ADO for talking to databases through recordsets Avoid if possible; use something more loosely coupled. SocketClass: Synchronous I/O to/from sockets WebClientClass: GET/PUT/POST/DELETE to a web server. Great for interacting with web services.
  • 19. Conditions and Reflection EnScript can eat its own tail First step: Conditions. Just a GUI for auto-generating code. To execute, you need ProgramClass Can execute as a Filter or as a normal script Conditions and ProgramClass objects require a SymbolClass object SymbolClass objects represent EnScript classes, PropertyClass objects represent class properties Reflection is the most powerful feature in EnScript Must use NodeClass to play with reflection
  • 20. Multithreading To create your own threads, inherit from ThreadClass and override Run() virtual function. Use the synchronized keyword to define critical sections. Global mutex across all threads. For finer-grained synchronization, can use SemaphoreClass… just as much of a pain as you can imagine. Prefer coarse-grained synchronization as much as possible. Multithreading can make a huge difference in the right situations, but use judiciously. Like any other language, don’t share objects between threads.