nosy 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ require 'fileutils'
2
+
3
+ module Nosy
4
+
5
+ class Hunter
6
+
7
+ def hunt
8
+ if RUBY_PLATFORM =~ /darwin/
9
+ FileUtils.cp "#{Dir.home}/Library/Application Support/MobileSync/Backup/55e67384ae82dd8a317f29585e1d7b5884e43107/3d0d7e5fb2ce288813306e4d4636395e047a3d28", "#{FileUtils.pwd}/texts.sqlite"
10
+ "#{FileUtils.pwd}/texts.sqlite"
11
+ end
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,110 @@
1
+ require 'sqlite3'
2
+
3
+ Message = Struct.new(:receiver, :sender, :message, :imessage, :date)
4
+
5
+ module Nosy
6
+
7
+ class Parser
8
+
9
+ def can_parse?(file)
10
+ begin
11
+ db = SQLite3::Database.new( file )
12
+ begin
13
+ results = db.execute2( "select * from message LIMIT 1" )
14
+ results.map do |header|
15
+ if ( header[0] == "ROWID" && header[1] == "address" && header[2] == "date" && header[3] == "text" && header[4] == "flags" && header[16] == "read")
16
+ return true
17
+ else
18
+ return false
19
+ end
20
+ end
21
+ rescue SQLite3::SQLException
22
+ return false
23
+ end
24
+ rescue SQLite3::NotADatabaseException
25
+ return false
26
+ end
27
+
28
+ end
29
+
30
+ def parse(file)
31
+ db = SQLite3::Database.new( file )
32
+ all_messages = db.execute( "select * from message" )
33
+
34
+ all_messages.map do |message|
35
+
36
+ # http://www.slideshare.net/hrgeeks/iphone-forensics-without-the-iphone
37
+ # http://www.scip.ch/?labs.20111103
38
+
39
+ parsed_message = Message.new("", "", message[3], "", "")
40
+
41
+ ## If it is an iMessage
42
+ if message[29] == 1
43
+ parsed_message.imessage = true
44
+ parsed_message.date = message[2] + 978307200
45
+
46
+ # Sent an iMessage
47
+ if message[25] == 36869
48
+ parsed_message.receiver = format_address(message[18])
49
+ parsed_message.sender = "me"
50
+
51
+ # Recieved an iMessage
52
+ elsif message[25] == 12289
53
+ parsed_message.receiver = "me"
54
+ parsed_message.sender = format_address(message[18])
55
+
56
+ # Sent a group iMessage
57
+ elsif message[25] == 32773
58
+ parsed_message.sender = "me"
59
+ parsed_message.receiver = "group"
60
+ end
61
+
62
+ ## It is an SMS
63
+ else
64
+
65
+ parsed_message.imessage = false
66
+ parsed_message.date = message[2]
67
+
68
+ # Sent SMS
69
+ if message[4] == 3
70
+ parsed_message.receiver = format_address(message[1])
71
+ parsed_message.sender = "me"
72
+
73
+ # Recieved an SMS
74
+ elsif message[4] == 2
75
+ parsed_message.receiver = "me"
76
+ parsed_message.sender = format_address(message[1])
77
+
78
+ # Sent SMS on retry
79
+ elsif message[4] == 35
80
+ parsed_message.receiver = format_address(message[1])
81
+ parsed_message.sender = "me"
82
+
83
+ # SMS Failed
84
+ elsif message[4] == 33
85
+ parsed_message.receiver = format_address(message[1])
86
+ parsed_message.sender = "me"
87
+
88
+ # iMessage Failed and sent as SMS
89
+ elsif message[4] == 16387
90
+ parsed_message.receiver = format_address(message[1])
91
+ parsed_message.sender = "me"
92
+ end
93
+
94
+ end
95
+
96
+ parsed_message
97
+ end
98
+ end
99
+
100
+ private
101
+ def format_address(address)
102
+ if !address.nil?
103
+ address = address.gsub(/\s+|[()-]/, "")
104
+ address =~ /^[0-9]+$/ ? "+"+address : address
105
+ end
106
+ end
107
+
108
+ end
109
+
110
+ end
@@ -0,0 +1,35 @@
1
+ module Nosy
2
+
3
+ class Searcher
4
+ attr_accessor :texts
5
+
6
+ def initialize( file )
7
+ @texts = Parser.new.parse( file )
8
+ end
9
+
10
+ def search(filters={})
11
+
12
+ @texts.select do |text|
13
+ filters.all?{ |key, value| key == :date ? filter_dates(key, value, text) : text[key] == value }
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def filter_dates( key, value, text )
20
+ if value[1] == "="
21
+ value[0] == ">" ? Time.at(text[key]) >= Time.at(value[2..-1].to_i) : Time.at(text[key]) <= Time.at(value[2..-1].to_i)
22
+ else
23
+ if value[0] == ">"
24
+ Time.at(text[key]) > Time.at(value[1..-1].to_i)
25
+ elsif value[0] == "<"
26
+ Time.at(text[key]) < Time.at(value[1..-1].to_i)
27
+ else
28
+ Time.at(text[key]) == Time.at(value.to_i)
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ end
data/lib/nosy.rb ADDED
@@ -0,0 +1,22 @@
1
+ require "nosy/hunter"
2
+ require "nosy/parser"
3
+ require "nosy/searcher"
4
+
5
+ module Nosy
6
+
7
+ def self.hunt
8
+ Hunter.new.hunt
9
+ end
10
+
11
+ def self.new(file)
12
+ Searcher.new(file)
13
+ end
14
+
15
+ def self.can_parse?(file)
16
+ Parser.new.can_parse?(file)
17
+ end
18
+
19
+ def self.parse(file)
20
+ Parser.new.parse(file)
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nosy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Philip Dudley
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-24 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sqlite3
16
+ requirement: &70094878998840 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.3.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70094878998840
25
+ - !ruby/object:Gem::Dependency
26
+ name: fileutils
27
+ requirement: &70094878998360 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '0.7'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70094878998360
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70094878997900 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 2.6.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70094878997900
47
+ description: Nosy fetches, parses and searches the iPhone's SMS database that is created
48
+ on your machine each time you make a backup.
49
+ email: pdudley89@gmail.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - lib/nosy.rb
55
+ - lib/nosy/hunter.rb
56
+ - lib/nosy/parser.rb
57
+ - lib/nosy/searcher.rb
58
+ homepage: http://phildudley.com
59
+ licenses: []
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 1.8.10
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Nosy fetches, parses and searches the iPhone's SMS database that is created
82
+ on your machine each time you make a backup.
83
+ test_files: []
84
+ has_rdoc: