123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- const fs = require('fs')
- const log = require('./log')
- const APPLE_2001_EPOCH = 978307200
- function parseCookie (cookieBuff) {
-
- function readNullTerminatedString (fromIndex) {
- let string = ''
- for (var i = fromIndex; cookieBuff.readInt8(i) !== 0 && i < size; i++) {
- string += String.fromCharCode(cookieBuff.readInt8(i))
- }
- return string
- }
- let size = cookieBuff.readInt32LE(0)
-
- let flagInt = cookieBuff.readInt32LE(8)
-
- let urlOffset = cookieBuff.readInt32LE(16)
- let nameOffset = cookieBuff.readInt32LE(20)
- let pathOffset = cookieBuff.readInt32LE(24)
- let valueOffset = cookieBuff.readInt32LE(28)
-
- let expirationEpoch = cookieBuff.readDoubleLE(40) + APPLE_2001_EPOCH
- let creationEpoch = cookieBuff.readDoubleLE(48) + APPLE_2001_EPOCH
-
- let flagDict = {
- 0: 'none',
- 1: 'secure',
- 4: 'httpOnly',
- 5: 'secure,httpOnly'
- }
- let flags = flagDict[flagInt]
- let url = readNullTerminatedString(urlOffset)
- let name = readNullTerminatedString(nameOffset)
- let path = readNullTerminatedString(pathOffset)
- let value = readNullTerminatedString(valueOffset)
- let expiration = new Date(expirationEpoch * 1000)
- let creation = new Date(creationEpoch * 1000)
- return { url, name, value, path, flags, creation, expiration }
- }
- function parsePage (page) {
- function checkPageHeader (page) {
- return page.readInt32BE(0) === 0x00000100
- }
-
- if (!checkPageHeader(page)) {
- return []
- }
-
- const cookieCount = page.readInt32LE(4)
-
- let cookies = []
- for (let i = 0; i < cookieCount; i++) {
-
- const cookieOffset = page.readInt32LE(8 + i * 4)
- const cookieSize = page.readInt32LE(cookieOffset)
-
- const cookieBuff = page.slice(cookieOffset, cookieOffset + cookieSize)
-
- let cookie = parseCookie(cookieBuff)
-
- if (cookie) {
- cookies.push(cookie)
- }
- }
- return cookies
- }
- function parseBase (buff) {
- function checkHeader (buff) {
- return buff.readInt8(0) === 'c'.charCodeAt(0) &&
- buff.readInt8(1) === 'o'.charCodeAt(0) &&
- buff.readInt8(2) === 'o'.charCodeAt(0) &&
- buff.readInt8(3) === 'k'.charCodeAt(0)
- }
-
- if (!checkHeader(buff)) {
- return []
- }
- let pageCount = buff.readInt32BE(4)
- let dataStart = (pageCount * 4) + 8
- let cursor = dataStart
- let cookies = []
- for (let i = 0; i < pageCount; i++) {
-
- let pageSize = buff.readInt32BE(8 + i * 4)
- let page = buff.slice(cursor, cursor + pageSize)
- cookies = [...cookies, ...parsePage(page)]
-
- cursor += pageSize
- }
- return cookies
- }
- module.exports.parse = function (filePath) {
- return new Promise((resolve, reject) => {
- log.verbose('parse', filePath)
- try {
- let buff = fs.readFileSync(filePath)
- let result = parseBase(buff)
-
- resolve(result)
- } catch (e) {
- return reject(e)
- }
- })
- }
|