Skip to content

Commit

Permalink
Migrated plaso timestamp to dfdatetime for SQLite plugins log2timelin…
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz committed Dec 30, 2016
1 parent 56eb178 commit 407dd33
Show file tree
Hide file tree
Showing 39 changed files with 1,566 additions and 1,491 deletions.
1 change: 1 addition & 0 deletions plaso/formatters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from plaso.formatters import android_app_usage
from plaso.formatters import android_calls
from plaso.formatters import android_sms
from plaso.formatters import android_webviewcache
from plaso.formatters import appcompatcache
from plaso.formatters import appusage
from plaso.formatters import asl
Expand Down
16 changes: 10 additions & 6 deletions plaso/formatters/android_webview.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
"""The Android WebViewCache database event formatter."""
"""The Android WebView database event formatter."""

from plaso.formatters import interface
from plaso.formatters import manager

class WebViewCookieExpiryEventFormatter(interface.ConditionalEventFormatter):
"""Formatter for an Android WebView Cookie Expiry event."""

DATA_TYPE = u'webview:cookie:expiry'
class AndroidWebViewCookieEventFormatter(interface.ConditionalEventFormatter):
"""Formatter for Android WebView Cookie event data."""

DATA_TYPE = u'webview:cookie'

FORMAT_STRING_PIECES = [
u'Domain: {domain}',
Expand All @@ -16,10 +17,13 @@ class WebViewCookieExpiryEventFormatter(interface.ConditionalEventFormatter):
u'Value: {value}',
u'Secure: {secure}',]

FORMAT_STRING_SHORT_PIECES = [u'{domain}', u'{name}', u'{value}']
FORMAT_STRING_SHORT_PIECES = [
u'{domain}',
u'{name}',
u'{value}']

SOURCE_LONG = u'Android WebView'
SOURCE_SHORT = u'WebView'


manager.FormattersManager.RegisterFormatter(WebViewCookieExpiryEventFormatter)
manager.FormattersManager.RegisterFormatter(AndroidWebViewCookieEventFormatter)
28 changes: 9 additions & 19 deletions plaso/formatters/android_webviewcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,21 @@
from plaso.formatters import manager


class WebViewCacheFormatter(interface.ConditionalEventFormatter):
"""Parent class for Android WebViewCache formatters."""
# TODO: move to android_webview.py.
class AndroidWebViewCacheFormatter(interface.ConditionalEventFormatter):
"""Formatter for Android WebViewCache event data."""

DATA_TYPE = u'android:webviewcache'

FORMAT_STRING_PIECES = [
u'URL: {url}',
u'Content Length: {content_length}',]
u'Content Length: {content_length}']

FORMAT_STRING_SHORT_PIECES = [u'url']
FORMAT_STRING_SHORT_PIECES = [
u'{url}']

SOURCE_LONG = u'Android WebViewCache'
SOURCE_SHORT = u'WebViewCache'


class WebViewCacheURLExpirationEventFormatter(WebViewCacheFormatter):
"""Formatter for an Android WebViewCache URL expiry event."""

DATA_TYPE = u'android:webviewcache:url_expiry'


class WebViewCacheURLModificationEventFormatter(WebViewCacheFormatter):
"""Formatter for an Android WebViewCache URL expiry event."""

DATA_TYPE = u'android:webviewcache:url_modification'


manager.FormattersManager.RegisterFormatters([
WebViewCacheURLExpirationEventFormatter,
WebViewCacheURLModificationEventFormatter])
manager.FormattersManager.RegisterFormatter(AndroidWebViewCacheFormatter)
48 changes: 48 additions & 0 deletions plaso/formatters/gdrive.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from plaso.formatters import interface
from plaso.formatters import manager
from plaso.lib import errors


__author__ = 'David Nides ([email protected])'
Expand All @@ -25,6 +26,53 @@ class GDriveCloudEntryFormatter(interface.ConditionalEventFormatter):
SOURCE_LONG = u'Google Drive (cloud entry)'
SOURCE_SHORT = u'LOG'

# The following definition for values can be found on Patrick Olson's blog:
# http://www.sysforensics.org/2012/05/google-drive-forensics-notes.html
_DOC_TYPES = {
0: u'FOLDER',
1: u'FILE',
2: u'PRESENTATION',
3: u'UNKNOWN',
4: u'SPREADSHEET',
5: u'DRAWING',
6: u'DOCUMENT',
7: u'TABLE',
}

def GetMessages(self, unused_formatter_mediator, event):
"""Determines the formatted message strings for an event object.
Args:
formatter_mediator (FormatterMediator): mediates the interactions between
formatters and other components, such as storage and Windows EventLog
resources.
event (EventObject): event.
Returns:
tuple(str, str): formatted message string and short message string.
Raises:
WrongFormatter: if the event object cannot be formatted by the formatter.
"""
if self.DATA_TYPE != event.data_type:
raise errors.WrongFormatter(u'Unsupported data type: {0:s}.'.format(
event.data_type))

event_values = event.CopyToDict()

document_type = event_values.get(u'document_type', None)
if document_type:
event_values[u'document_type'] = self._DOC_TYPES.get(
document_type, u'UNKNOWN')

shared = event_values.get(u'shared', False)
if shared:
event_values[u'shared'] = u'Shared'
else:
event_values[u'shared'] = u'Private'

return self._ConditionalFormatMessages(event_values)


class GDriveLocalEntryFormatter(interface.ConditionalEventFormatter):
"""Formatter for a Google Drive snapshot local event."""
Expand Down
39 changes: 11 additions & 28 deletions plaso/formatters/twitter_ios.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@


class TwitterIOSContactFormatter(interface.ConditionalEventFormatter):
"""Parent class for Twitter on iOS 8+ contacts formatters."""
"""Twitter on iOS 8+ contact event formatter."""

DATA_TYPE = u'twitter:ios:contact'

FORMAT_STRING_PIECES = [
u'Screen name: {screen_name}',
Expand All @@ -17,8 +19,8 @@ class TwitterIOSContactFormatter(interface.ConditionalEventFormatter):
u'Description: {description}',
u'URL: {url}',
u'Following: {following}',
u'Number of followers: {followers_cnt}',
u'Number of following: {following_cnt}',
u'Number of followers: {followers_count}',
u'Number of following: {following_count}',
]

FORMAT_STRING_SHORT_PIECES = [
Expand Down Expand Up @@ -64,26 +66,18 @@ def GetMessages(self, unused_formatter_mediator, event):
return self._ConditionalFormatMessages(event_values)


class TwitterIOSContactCreationFormatter(TwitterIOSContactFormatter):
"""Formatter for Twitter on iOS 8+ contacts creation event."""
DATA_TYPE = u'twitter:ios:contact_creation'


class TwitterIOSContactUpdateFormatter(TwitterIOSContactFormatter):
"""Formatter for Twitter on iOS 8+ contacts update event."""
DATA_TYPE = u'twitter:ios:contact_update'


class TwitterIOSStatusFormatter(interface.ConditionalEventFormatter):
"""Parent class for Twitter on iOS 8+ status formatters."""
"""Twitter on iOS 8+ status event formatter."""

DATA_TYPE = u'twitter:ios:status'

FORMAT_STRING_PIECES = [
u'Name: {name}',
u'User Id: {user_id}',
u'Message: {text}',
u'Favorite: {favorited}',
u'Retweet Count: {retweet_cnt}',
u'Favorite Count: {favorite_cnt}',
u'Retweet Count: {retweet_count}',
u'Favorite Count: {favorite_count}',
]

FORMAT_STRING_SHORT_PIECES = [
Expand Down Expand Up @@ -128,16 +122,5 @@ def GetMessages(self, unused_formatter_mediator, event):
return self._ConditionalFormatMessages(event_values)


class TwitterIOSStatusCreationFormatter(TwitterIOSStatusFormatter):
"""Formatter for Twitter on iOS 8+ status creation event."""
DATA_TYPE = u'twitter:ios:status_creation'


class TwitterIOSStatusUpdateFormatter(TwitterIOSStatusFormatter):
"""Formatter for Twitter on iOS 8+ status update event."""
DATA_TYPE = u'twitter:ios:status_update'


manager.FormattersManager.RegisterFormatters([
TwitterIOSContactCreationFormatter, TwitterIOSContactUpdateFormatter,
TwitterIOSStatusCreationFormatter, TwitterIOSStatusUpdateFormatter])
TwitterIOSContactFormatter, TwitterIOSStatusFormatter])
83 changes: 45 additions & 38 deletions plaso/parsers/sqlite_plugins/android_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,34 @@
Android Call History is stored in SQLite database files named contacts2.db.
"""

from dfdatetime import java_time as dfdatetime_java_time

from plaso.containers import events
from plaso.containers import time_events
from plaso.lib import py2to3
from plaso.parsers import sqlite
from plaso.parsers.sqlite_plugins import interface


class AndroidCallEvent(time_events.JavaTimeEvent):
"""Convenience class for an Android Call History event."""
class AndroidCallEventData(events.EventData):
"""Android Call event data.
DATA_TYPE = u'android:event:call'
Attributes:
call_type (str): type of call, such as: Incoming, Outgoing, or Missed.
duration (int): number of seconds the call lasted.
name (str): name associated to the remote party.
number (str): phone number associated to the remote party.
"""

def __init__(
self, java_time, usage, identifier, number, name, duration, call_type):
"""Initializes the event object.
DATA_TYPE = u'android:event:call'

Args:
java_time: The Java time value.
usage: The description of the usage of the time value.
identifier: The row identifier.
number: The phone number associated to the remote party.
duration: The number of seconds the call lasted.
call_type: Incoming, Outgoing, or Missed.
"""
super(AndroidCallEvent, self).__init__(java_time, usage)
self.offset = identifier
self.number = number
self.name = name
self.duration = duration
self.call_type = call_type
def __init__(self):
"""Initializes event data."""
super(AndroidCallEventData, self).__init__(data_type=self.DATA_TYPE)
self.call_type = None
self.duration = None
self.name = None
self.number = None


class AndroidCallPlugin(interface.SQLitePlugin):
Expand All @@ -57,35 +56,43 @@ def ParseCallsRow(self, parser_mediator, row, query=None, **unused_kwargs):
"""Parses a Call record row.
Args:
parser_mediator: A parser mediator object (instance of ParserMediator).
row: The row resulting from the query.
query: Optional query string.
parser_mediator (ParserMediator): mediates interactions between parsers
and other components, such as storage and dfvfs.
row (sqlite3.Row): row.
query (Optional[str]): query.
"""
# Note that pysqlite does not accept a Unicode string in row['string'] and
# will raise "IndexError: Index must be int or string".

call_type = self.CALL_TYPE.get(row['type'], u'UNKNOWN')
duration = row['duration']
timestamp = row['date']

event_object = AndroidCallEvent(
row['date'], u'Call Started', row['id'], row['number'], row['name'],
row['duration'], call_type)
parser_mediator.ProduceEvent(event_object, query=query)
event_data = AndroidCallEventData()
event_data.call_type = call_type
event_data.duration = row['duration']
event_data.name = row['name']
event_data.number = row['number']
event_data.offset = row['id']
event_data.query = query

duration = row['duration']
if isinstance(duration, py2to3.STRING_TYPES):
try:
duration = int(duration, 10)
except ValueError:
duration = 0
date_time = dfdatetime_java_time.JavaTime(timestamp=timestamp)
event = time_events.DateTimeValuesEvent(date_time, u'Call Started')
parser_mediator.ProduceEventWithEventData(event, event_data)

if duration:
if isinstance(duration, py2to3.STRING_TYPES):
try:
duration = int(duration, 10)
except ValueError:
duration = 0

# The duration is in seconds and the date value in milliseconds.
duration *= 1000
event_object = AndroidCallEvent(
row['date'] + duration, u'Call Ended', row['id'], row['number'],
row['name'], row['duration'], call_type)
parser_mediator.ProduceEvent(event_object, query=query)
timestamp += duration * 1000

date_time = dfdatetime_java_time.JavaTime(timestamp=timestamp)
event = time_events.DateTimeValuesEvent(date_time, u'Call Ended')
parser_mediator.ProduceEventWithEventData(event, event_data)


sqlite.SQLiteParser.RegisterPlugin(AndroidCallPlugin)
Loading

0 comments on commit 407dd33

Please sign in to comment.