From 3fe37ec7b1702f8eeada4c6e65642dff202e04a5 Mon Sep 17 00:00:00 2001 From: Nbblrr Date: Sat, 5 Jan 2013 00:03:25 +0100 Subject: [PATCH 1/2] Improved Hardware detection with mdetect. Ticket #722 --- core/main/client/hardware.js | 70 +- core/main/client/lib/mdetect.js | 961 +++++++++++++++++++++++++++ core/main/handlers/modules/beefjs.rb | 4 +- extensions/evasion/config.yaml | 2 +- 4 files changed, 1015 insertions(+), 22 deletions(-) create mode 100644 core/main/client/lib/mdetect.js diff --git a/core/main/client/hardware.js b/core/main/client/hardware.js index 5e64e9ab2..01f69dc50 100644 --- a/core/main/client/hardware.js +++ b/core/main/client/hardware.js @@ -7,11 +7,11 @@ beef.hardware = { ua: navigator.userAgent, - + isWinPhone: function() { return (this.ua.match('(Windows Phone)')) ? true : false; }, - + isIphone: function() { return (this.ua.indexOf('iPhone') != -1) ? true : false; }, @@ -48,10 +48,6 @@ beef.hardware = { return (this.ua.match('Ericsson')) ? true : false; }, - isNokia: function() { - return (this.ua.match('Nokia')) ? true : false; - }, - isMotorola: function() { return (this.ua.match('Motorola')) ? true : false; }, @@ -60,20 +56,56 @@ beef.hardware = { return (this.ua.match('Nexus One')) ? true : false; }, - getName: function() { + /** + * Returns true if the browser is on a Mobile Phone + * @return: {Boolean} true or false + * + * @example: if(beef.browser.isMobilePhone()) { ... } + **/ + isMobilePhone: function() { + return DetectMobileQuick(); + }, - if (this.isNokia()) return 'Nokia'; - if (this.isWinPhone()) return 'Windows Phone'; - if (this.isBlackBerry()) return 'BlackBerry'; - if (this.isIphone()) return 'iPhone'; - if (this.isIpad()) return 'iPad'; - if (this.isIpod()) return 'iPod'; - if (this.isKindle()) return 'Kindle'; - if (this.isHtc()) return 'HTC'; - if (this.isMotorola()) return 'Motorola'; - if (this.isZune()) return 'Zune'; - if (this.isGoogle()) return 'Google'; - if (this.isEricsson()) return 'Ericsson'; + getName: function() { + var ua = navigator.userAgent; + if(DetectIphone()) { return "iPhone"}; + if(DetectIpod()) { return "iPod Touch"}; + if(DetectIpad()) { return "iPad"}; + if (this.isHtc()) { return 'HTC'}; + if (this.isMotorola()) { return 'Motorola'}; + if (this.isZune()) { return 'Zune'}; + if (this.isGoogle()) { return 'Google'}; + if (this.isEricsson()) { return 'Ericsson'}; + if(DetectAndroidPhone()) { return "Android Phone"}; + if(DetectAndroidTablet()) { return "Android Tablet"}; + if(DetectS60OssBrowser()) { return "Nokia S60 Open Source"}; + if(ua.search(deviceS60) > -1) { return "Nokia S60"}; + if(ua.search(deviceS70) > -1) { return "Nokia S70"}; + if(ua.search(deviceS80) > -1) { return "Nokia S80"}; + if(ua.search(deviceS90) > -1) { return "Nokia Symbian"}; + if (this.isNokia()) { return 'Nokia'}; + if(DetectWindowsPhone7()) { return "Windows Phone 7"}; + if(DetectWindowsMobile()) { return "Windows Mobile"}; + if(DetectBlackBerryTablet()) { return "BlackBerry Tablet"}; + if(DetectBlackBerryWebKit()) { return "BlackBerry OS 6"}; + if(DetectBlackBerryTouch()) { return "BlackBerry Touch"}; + if(DetectBlackBerryHigh()) { return "BlackBerry OS 5"}; + if(DetectBlackBerry()) { return "BlackBerry"}; + if(DetectPalmOS()) { return "Palm OS"}; + if(DetectPalmWebOS()) { return "Palm Web OS"}; + if(DetectGarminNuvifone()) { return "Gamin Nuvifone"}; + if(DetectArchos()) { return "Archos"} + if(DetectBrewDevice()) { return "Brew"}; + if(DetectDangerHiptop()) { return "Danger Hiptop"}; + if(DetectMaemoTablet()) { return "Maemo Tablet"}; + if(DetectSonyMylo()) { return "Sony Mylo"}; + if(DetectAmazonSilk()) { return "Kindle Fire"}; + if(DetectKindle()) { return "Kindle"}; + if(DetectSonyPlaystation()) { return "Playstation" }; + if(ua.search(deviceNintendoDs) > -1) { return "Nintendo DS"}; + if(ua.search(deviceWii) > -1) { return "Nintendo Wii"}; + if(ua.search(deviceNintendo) > -1) { return "Nintendo"}; + if(DetectXbox()) { return "Xbox"}; return 'Unknown'; } diff --git a/core/main/client/lib/mdetect.js b/core/main/client/lib/mdetect.js new file mode 100644 index 000000000..85de2b29e --- /dev/null +++ b/core/main/client/lib/mdetect.js @@ -0,0 +1,961 @@ + +/* ******************************************* +// Copyright 2010-2012, Anthony Hand +// +// File version date: April 23, 2012 +// Update: +// - Updated DetectAmazonSilk(): Fixed an issue in the detection logic. +// +// File version date: April 22, 2012 - Second update +// Update: To address additional Kindle issues... +// - Updated DetectRichCSS(): Excluded e-Ink Kindle devices. +// - Created DetectAmazonSilk(): Created to detect Kindle Fire devices in Silk mode. +// - Updated DetectMobileQuick(): Updated to include e-Ink Kindle devices and the Kindle Fire in Silk mode. +// +// File version date: April 11, 2012 +// Update: +// - Added a new variable for the new BlackBerry Curve Touch (9380): deviceBBCurveTouch. +// - Updated DetectBlackBerryTouch() to support the new BlackBerry Curve Touch (9380). +// +// File version date: January 21, 2012 +// Update: +// - Moved Windows Phone 7 to the iPhone Tier. WP7.5's IE 9-based browser is good enough now. +// - Added a new variable for 2 versions of the new BlackBerry Bold Touch (9900 and 9930): deviceBBBoldTouch. +// - Updated DetectBlackBerryTouch() to support the 2 versions of the new BlackBerry Bold Touch (9900 and 9930). +// - Updated DetectKindle() to focus on eInk devices only. The Kindle Fire should be detected as a regular Android device. +// +// File version date: August 22, 2011 +// Update: +// - Updated DetectAndroidTablet() to fix a bug introduced in the last fix! The true/false returns were mixed up. +// +// File version date: August 16, 2011 +// Update: +// - Updated DetectAndroidTablet() to exclude Opera Mini, which was falsely reporting as running on a tablet device when on a phone. +// - Updated the user agent (uagent) init technique to handle spiders and such with null values. +// +// +// LICENSE INFORMATION +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific +// language governing permissions and limitations under the License. +// +// +// ABOUT THIS PROJECT +// Project Owner: Anthony Hand +// Email: anthony.hand@gmail.com +// Web Site: http://www.mobileesp.com +// Source Files: http://code.google.com/p/mobileesp/ +// +// Versions of this code are available for: +// PHP, JavaScript, Java, ASP.NET (C#), and Ruby +// +// +// WARNING: +// These JavaScript-based device detection features may ONLY work +// for the newest generation of smartphones, such as the iPhone, +// Android and Palm WebOS devices. +// These device detection features may NOT work for older smartphones +// which had poor support for JavaScript, including +// older BlackBerry, PalmOS, and Windows Mobile devices. +// Additionally, because JavaScript support is extremely poor among +// 'feature phones', these features may not work at all on such devices. +// For better results, consider using a server-based version of this code, +// such as Java, APS.NET, PHP, or Ruby. +// +// ******************************************* +*/ + +//Optional: Store values for quickly accessing same info multiple times. +//Note: These values are not set automatically. +//Stores whether the device is an iPhone or iPod Touch. +var isIphone = false; +//Stores whether the device is an Android phone or multi-media player. +var isAndroidPhone = false; +//Stores whether is the Tablet (HTML5-capable, larger screen) tier of devices. +var isTierTablet = false; +//Stores whether is the iPhone tier of devices. +var isTierIphone = false; +//Stores whether the device can probably support Rich CSS, but JavaScript support is not assumed. (e.g., newer BlackBerry, Windows Mobile) +var isTierRichCss = false; +//Stores whether it is another mobile device, which cannot be assumed to support CSS or JS (eg, older BlackBerry, RAZR) +var isTierGenericMobile = false; + +//Initialize some initial string variables we'll look for later. +var engineWebKit = "webkit"; +var deviceIphone = "iphone"; +var deviceIpod = "ipod"; +var deviceIpad = "ipad"; +var deviceMacPpc = "macintosh"; //Used for disambiguation + +var deviceAndroid = "android"; +var deviceGoogleTV = "googletv"; +var deviceXoom = "xoom"; //Motorola Xoom +var deviceHtcFlyer = "htc_flyer"; //HTC Flyer + +var deviceNuvifone = "nuvifone"; //Garmin Nuvifone + +var deviceSymbian = "symbian"; +var deviceS60 = "series60"; +var deviceS70 = "series70"; +var deviceS80 = "series80"; +var deviceS90 = "series90"; + +var deviceWinPhone7 = "windows phone os 7"; +var deviceWinMob = "windows ce"; +var deviceWindows = "windows"; +var deviceIeMob = "iemobile"; +var devicePpc = "ppc"; //Stands for PocketPC +var enginePie = "wm5 pie"; //An old Windows Mobile + +var deviceBB = "blackberry"; +var vndRIM = "vnd.rim"; //Detectable when BB devices emulate IE or Firefox +var deviceBBStorm = "blackberry95"; //Storm 1 and 2 +var deviceBBBold = "blackberry97"; //Bold 97x0 (non-touch) +var deviceBBBoldTouch = "blackberry 99"; //Bold 99x0 (touchscreen) +var deviceBBTour = "blackberry96"; //Tour +var deviceBBCurve = "blackberry89"; //Curve 2 +var deviceBBCurveTouch = "blackberry 938"; //Curve Touch 9380 +var deviceBBTorch = "blackberry 98"; //Torch +var deviceBBPlaybook = "playbook"; //PlayBook tablet + +var devicePalm = "palm"; +var deviceWebOS = "webos"; //For Palm's line of WebOS devices +var deviceWebOShp = "hpwos"; //For HP's line of WebOS devices + +var engineBlazer = "blazer"; //Old Palm browser +var engineXiino = "xiino"; + +var deviceKindle = "kindle"; //Amazon Kindle, eInk one +var engineSilk = "silk"; //Amazon's accelerated Silk browser for Kindle Fire + +//Initialize variables for mobile-specific content. +var vndwap = "vnd.wap"; +var wml = "wml"; + +//Initialize variables for random devices and mobile browsers. +//Some of these may not support JavaScript +var deviceTablet = "tablet"; //Generic term for slate and tablet devices +var deviceBrew = "brew"; +var deviceDanger = "danger"; +var deviceHiptop = "hiptop"; +var devicePlaystation = "playstation"; +var deviceNintendoDs = "nitro"; +var deviceNintendo = "nintendo"; +var deviceWii = "wii"; +var deviceXbox = "xbox"; +var deviceArchos = "archos"; + +var engineOpera = "opera"; //Popular browser +var engineNetfront = "netfront"; //Common embedded OS browser +var engineUpBrowser = "up.browser"; //common on some phones +var engineOpenWeb = "openweb"; //Transcoding by OpenWave server +var deviceMidp = "midp"; //a mobile Java technology +var uplink = "up.link"; +var engineTelecaQ = 'teleca q'; //a modern feature phone browser + +var devicePda = "pda"; +var mini = "mini"; //Some mobile browsers put 'mini' in their names. +var mobile = "mobile"; //Some mobile browsers put 'mobile' in their user agent strings. +var mobi = "mobi"; //Some mobile browsers put 'mobi' in their user agent strings. + +//Use Maemo, Tablet, and Linux to test for Nokia's Internet Tablets. +var maemo = "maemo"; +var linux = "linux"; +var qtembedded = "qt embedded"; //for Sony Mylo and others +var mylocom2 = "com2"; //for Sony Mylo also + +//In some UserAgents, the only clue is the manufacturer. +var manuSonyEricsson = "sonyericsson"; +var manuericsson = "ericsson"; +var manuSamsung1 = "sec-sgh"; +var manuSony = "sony"; +var manuHtc = "htc"; //Popular Android and WinMo manufacturer + +//In some UserAgents, the only clue is the operator. +var svcDocomo = "docomo"; +var svcKddi = "kddi"; +var svcVodafone = "vodafone"; + +//Disambiguation strings. +var disUpdate = "update"; //pda vs. update + + + +//Initialize our user agent string. +var uagent = ""; +if (navigator && navigator.userAgent) + uagent = navigator.userAgent.toLowerCase(); + + +//************************** +// Detects if the current device is an iPhone. +function DetectIphone() +{ + if (uagent.search(deviceIphone) > -1) + { + //The iPad and iPod Touch say they're an iPhone! So let's disambiguate. + if (DetectIpad() || DetectIpod()) + return false; + //Yay! It's an iPhone! + else + return true; + } + else + return false; +} + +//************************** +// Detects if the current device is an iPod Touch. +function DetectIpod() +{ + if (uagent.search(deviceIpod) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current device is an iPad tablet. +function DetectIpad() +{ + if (uagent.search(deviceIpad) > -1 && DetectWebkit()) + return true; + else + return false; +} + +//************************** +// Detects if the current device is an iPhone or iPod Touch. +function DetectIphoneOrIpod() +{ + //We repeat the searches here because some iPods + // may report themselves as an iPhone, which is ok. + if (uagent.search(deviceIphone) > -1 || + uagent.search(deviceIpod) > -1) + return true; + else + return false; +} + +//************************** +// Detects *any* iOS device: iPhone, iPod Touch, iPad. +function DetectIos() +{ + if (DetectIphoneOrIpod() || DetectIpad()) + return true; + else + return false; +} + +//************************** +// Detects *any* Android OS-based device: phone, tablet, and multi-media player. +// Also detects Google TV. +function DetectAndroid() +{ + if ((uagent.search(deviceAndroid) > -1) || DetectGoogleTV()) + return true; + //Special check for the HTC Flyer 7" tablet. It should report here. + if (uagent.search(deviceHtcFlyer) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current device is a (small-ish) Android OS-based device +// used for calling and/or multi-media (like a Samsung Galaxy Player). +// Google says these devices will have 'Android' AND 'mobile' in user agent. +// Ignores tablets (Honeycomb and later). +function DetectAndroidPhone() +{ + if (DetectAndroid() && (uagent.search(mobile) > -1)) + return true; + //Special check for Android phones with Opera Mobile. They should report here. + if (DetectOperaAndroidPhone()) + return true; + //Special check for the HTC Flyer 7" tablet. It should report here. + if (uagent.search(deviceHtcFlyer) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current device is a (self-reported) Android tablet. +// Google says these devices will have 'Android' and NOT 'mobile' in their user agent. +function DetectAndroidTablet() +{ + //First, let's make sure we're on an Android device. + if (!DetectAndroid()) + return false; + + //Special check for Opera Android Phones. They should NOT report here. + if (DetectOperaMobile()) + return false; + //Special check for the HTC Flyer 7" tablet. It should NOT report here. + if (uagent.search(deviceHtcFlyer) > -1) + return false; + + //Otherwise, if it's Android and does NOT have 'mobile' in it, Google says it's a tablet. + if (uagent.search(mobile) > -1) + return false; + else + return true; +} + + +//************************** +// Detects if the current device is an Android OS-based device and +// the browser is based on WebKit. +function DetectAndroidWebKit() +{ + if (DetectAndroid() && DetectWebkit()) + return true; + else + return false; +} + + +//************************** +// Detects if the current device is a GoogleTV. +function DetectGoogleTV() +{ + if (uagent.search(deviceGoogleTV) > -1) + return true; + else + return false; +} + + +//************************** +// Detects if the current browser is based on WebKit. +function DetectWebkit() +{ + if (uagent.search(engineWebKit) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is the Nokia S60 Open Source Browser. +function DetectS60OssBrowser() +{ + if (DetectWebkit()) + { + if ((uagent.search(deviceS60) > -1 || + uagent.search(deviceSymbian) > -1)) + return true; + else + return false; + } + else + return false; +} + +//************************** +// Detects if the current device is any Symbian OS-based device, +// including older S60, Series 70, Series 80, Series 90, and UIQ, +// or other browsers running on these devices. +function DetectSymbianOS() +{ + if (uagent.search(deviceSymbian) > -1 || + uagent.search(deviceS60) > -1 || + uagent.search(deviceS70) > -1 || + uagent.search(deviceS80) > -1 || + uagent.search(deviceS90) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is a +// Windows Phone 7 device. +function DetectWindowsPhone7() +{ + if (uagent.search(deviceWinPhone7) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is a Windows Mobile device. +// Excludes Windows Phone 7 devices. +// Focuses on Windows Mobile 6.xx and earlier. +function DetectWindowsMobile() +{ + //Exclude new Windows Phone 7. + if (DetectWindowsPhone7()) + return false; + //Most devices use 'Windows CE', but some report 'iemobile' + // and some older ones report as 'PIE' for Pocket IE. + if (uagent.search(deviceWinMob) > -1 || + uagent.search(deviceIeMob) > -1 || + uagent.search(enginePie) > -1) + return true; + //Test for Windows Mobile PPC but not old Macintosh PowerPC. + if ((uagent.search(devicePpc) > -1) && + !(uagent.search(deviceMacPpc) > -1)) + return true; + //Test for Windwos Mobile-based HTC devices. + if (uagent.search(manuHtc) > -1 && + uagent.search(deviceWindows) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is a BlackBerry of some sort. +// Includes the PlayBook. +function DetectBlackBerry() +{ + if (uagent.search(deviceBB) > -1) + return true; + if (uagent.search(vndRIM) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is on a BlackBerry tablet device. +// Example: PlayBook +function DetectBlackBerryTablet() +{ + if (uagent.search(deviceBBPlaybook) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is a BlackBerry device AND uses a +// WebKit-based browser. These are signatures for the new BlackBerry OS 6. +// Examples: Torch. Includes the Playbook. +function DetectBlackBerryWebKit() +{ + if (DetectBlackBerry() && + uagent.search(engineWebKit) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is a BlackBerry Touch +// device, such as the Storm, Torch, and Bold Touch. Excludes the Playbook. +function DetectBlackBerryTouch() +{ + if (DetectBlackBerry() && + ((uagent.search(deviceBBStorm) > -1) || + (uagent.search(deviceBBTorch) > -1) || + (uagent.search(deviceBBBoldTouch) > -1) || + (uagent.search(deviceBBCurveTouch) > -1) )) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is a BlackBerry OS 5 device AND +// has a more capable recent browser. Excludes the Playbook. +// Examples, Storm, Bold, Tour, Curve2 +// Excludes the new BlackBerry OS 6 and 7 browser!! +function DetectBlackBerryHigh() +{ + //Disambiguate for BlackBerry OS 6 or 7 (WebKit) browser + if (DetectBlackBerryWebKit()) + return false; + if (DetectBlackBerry()) + { + if (DetectBlackBerryTouch() || + uagent.search(deviceBBBold) > -1 || + uagent.search(deviceBBTour) > -1 || + uagent.search(deviceBBCurve) > -1) + return true; + else + return false; + } + else + return false; +} + +//************************** +// Detects if the current browser is a BlackBerry device AND +// has an older, less capable browser. +// Examples: Pearl, 8800, Curve1. +function DetectBlackBerryLow() +{ + if (DetectBlackBerry()) + { + //Assume that if it's not in the High tier or has WebKit, then it's Low. + if (DetectBlackBerryHigh() || DetectBlackBerryWebKit()) + return false; + else + return true; + } + else + return false; +} + + +//************************** +// Detects if the current browser is on a PalmOS device. +function DetectPalmOS() +{ + //Most devices nowadays report as 'Palm', + // but some older ones reported as Blazer or Xiino. + if (uagent.search(devicePalm) > -1 || + uagent.search(engineBlazer) > -1 || + uagent.search(engineXiino) > -1) + { + //Make sure it's not WebOS first + if (DetectPalmWebOS()) + return false; + else + return true; + } + else + return false; +} + +//************************** +// Detects if the current browser is on a Palm device +// running the new WebOS. +function DetectPalmWebOS() +{ + if (uagent.search(deviceWebOS) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is on an HP tablet running WebOS. +function DetectWebOSTablet() +{ + if (uagent.search(deviceWebOShp) > -1 && + uagent.search(deviceTablet) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is a +// Garmin Nuvifone. +function DetectGarminNuvifone() +{ + if (uagent.search(deviceNuvifone) > -1) + return true; + else + return false; +} + + +//************************** +// Check to see whether the device is a 'smartphone'. +// You might wish to send smartphones to a more capable web page +// than a dumbed down WAP page. +function DetectSmartphone() +{ + if (DetectIphoneOrIpod() + || DetectAndroidPhone() + || DetectS60OssBrowser() + || DetectSymbianOS() + || DetectWindowsMobile() + || DetectWindowsPhone7() + || DetectBlackBerry() + || DetectPalmWebOS() + || DetectPalmOS() + || DetectGarminNuvifone()) + return true; + + //Otherwise, return false. + return false; +}; + +//************************** +// Detects if the current device is an Archos media player/Internet tablet. +function DetectArchos() +{ + if (uagent.search(deviceArchos) > -1) + return true; + else + return false; +} + +//************************** +// Detects whether the device is a Brew-powered device. +function DetectBrewDevice() +{ + if (uagent.search(deviceBrew) > -1) + return true; + else + return false; +} + +//************************** +// Detects the Danger Hiptop device. +function DetectDangerHiptop() +{ + if (uagent.search(deviceDanger) > -1 || + uagent.search(deviceHiptop) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current device is on one of +// the Maemo-based Nokia Internet Tablets. +function DetectMaemoTablet() +{ + if (uagent.search(maemo) > -1) + return true; + //For Nokia N810, must be Linux + Tablet, or else it could be something else. + if ((uagent.search(linux) > -1) + && (uagent.search(deviceTablet) > -1) + && !DetectWebOSTablet() + && !DetectAndroid()) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is a Sony Mylo device. +function DetectSonyMylo() +{ + if (uagent.search(manuSony) > -1) + { + if (uagent.search(qtembedded) > -1 || + uagent.search(mylocom2) > -1) + return true; + else + return false; + } + else + return false; +} + +//************************** +// Detects if the current browser is Opera Mobile or Mini. +function DetectOperaMobile() +{ + if (uagent.search(engineOpera) > -1) + { + if (uagent.search(mini) > -1 || + uagent.search(mobi) > -1) + return true; + else + return false; + } + else + return false; +} + +//************************** +// Detects if the current browser is Opera Mobile +// running on an Android phone. +function DetectOperaAndroidPhone() +{ + if ((uagent.search(engineOpera) > -1) && + (uagent.search(deviceAndroid) > -1) && + (uagent.search(mobi) > -1)) + return true; + else + return false; +} + +//************************** +// Detects if the current browser is Opera Mobile +// running on an Android tablet. +function DetectOperaAndroidTablet() +{ + if ((uagent.search(engineOpera) > -1) && + (uagent.search(deviceAndroid) > -1) && + (uagent.search(deviceTablet) > -1)) + return true; + else + return false; +} + +//************************** +// Detects if the current device is a Sony Playstation. +function DetectSonyPlaystation() +{ + if (uagent.search(devicePlaystation) > -1) + return true; + else + return false; +}; + +//************************** +// Detects if the current device is a Nintendo game device. +function DetectNintendo() +{ + if (uagent.search(deviceNintendo) > -1 || + uagent.search(deviceWii) > -1 || + uagent.search(deviceNintendoDs) > -1) + return true; + else + return false; +}; + +//************************** +// Detects if the current device is a Microsoft Xbox. +function DetectXbox() +{ + if (uagent.search(deviceXbox) > -1) + return true; + else + return false; +}; + +//************************** +// Detects if the current device is an Internet-capable game console. +function DetectGameConsole() +{ + if (DetectSonyPlaystation()) + return true; + if (DetectNintendo()) + return true; + if (DetectXbox()) + return true; + else + return false; +}; + +//************************** +// Detects if the current device is an Amazon Kindle (eInk devices only). +// Note: For the Kindle Fire, use the normal Android methods. +function DetectKindle() +{ + if (uagent.search(deviceKindle) > -1 && + !DetectAndroid()) + return true; + else + return false; +} + +//************************** +// Detects if the current Amazon device is using the Silk Browser. +// Note: Typically used by the the Kindle Fire. +function DetectAmazonSilk() +{ + if (uagent.search(engineSilk) > -1) + return true; + else + return false; +} + +//************************** +// Detects if the current device is a mobile device. +// This method catches most of the popular modern devices. +// Excludes Apple iPads and other modern tablets. +function DetectMobileQuick() +{ + //Let's exclude tablets. + if (DetectTierTablet()) + return false; + + //Most mobile browsing is done on smartphones + if (DetectSmartphone()) + return true; + + if (uagent.search(deviceMidp) > -1 || + DetectBrewDevice()) + return true; + + if (DetectOperaMobile()) + return true; + + if (uagent.search(engineNetfront) > -1) + return true; + if (uagent.search(engineUpBrowser) > -1) + return true; + if (uagent.search(engineOpenWeb) > -1) + return true; + + if (DetectDangerHiptop()) + return true; + + if (DetectMaemoTablet()) + return true; + if (DetectArchos()) + return true; + + if ((uagent.search(devicePda) > -1) && + !(uagent.search(disUpdate) > -1)) + return true; + if (uagent.search(mobile) > -1) + return true; + + if (DetectKindle() || + DetectAmazonSilk()) + return true; + + return false; +}; + + +//************************** +// Detects in a more comprehensive way if the current device is a mobile device. +function DetectMobileLong() +{ + if (DetectMobileQuick()) + return true; + if (DetectGameConsole()) + return true; + if (DetectSonyMylo()) + return true; + + //Detect for certain very old devices with stupid useragent strings. + if (uagent.search(manuSamsung1) > -1 || + uagent.search(manuSonyEricsson) > -1 || + uagent.search(manuericsson) > -1) + return true; + + if (uagent.search(svcDocomo) > -1) + return true; + if (uagent.search(svcKddi) > -1) + return true; + if (uagent.search(svcVodafone) > -1) + return true; + + + return false; +}; + + +//***************************** +// For Mobile Web Site Design +//***************************** + +//************************** +// The quick way to detect for a tier of devices. +// This method detects for the new generation of +// HTML 5 capable, larger screen tablets. +// Includes iPad, Android (e.g., Xoom), BB Playbook, WebOS, etc. +function DetectTierTablet() +{ + if (DetectIpad() + || DetectAndroidTablet() + || DetectBlackBerryTablet() + || DetectWebOSTablet()) + return true; + else + return false; +}; + +//************************** +// The quick way to detect for a tier of devices. +// This method detects for devices which can +// display iPhone-optimized web content. +// Includes iPhone, iPod Touch, Android, Windows Phone 7, WebOS, etc. +function DetectTierIphone() +{ + if (DetectIphoneOrIpod()) + return true; + if (DetectAndroidPhone()) + return true; + if (DetectBlackBerryWebKit() && DetectBlackBerryTouch()) + return true; + if (DetectWindowsPhone7()) + return true; + if (DetectPalmWebOS()) + return true; + if (DetectGarminNuvifone()) + return true; + else + return false; +}; + +//************************** +// The quick way to detect for a tier of devices. +// This method detects for devices which are likely to be +// capable of viewing CSS content optimized for the iPhone, +// but may not necessarily support JavaScript. +// Excludes all iPhone Tier devices. +function DetectTierRichCss() +{ + if (DetectMobileQuick()) + { + //Exclude iPhone Tier and e-Ink Kindle devices + if (DetectTierIphone() || DetectKindle()) + return false; + + //The following devices are explicitly ok. + if (DetectWebkit()) + return true; + if (DetectS60OssBrowser()) + return true; + + //Note: 'High' BlackBerry devices ONLY + if (DetectBlackBerryHigh()) + return true; + + //Older Windows 'Mobile' isn't good enough for iPhone Tier. + if (DetectWindowsMobile()) + return true; + + if (uagent.search(engineTelecaQ) > -1) + return true; + + else + return false; + } + else + return false; +}; + +//************************** +// The quick way to detect for a tier of devices. +// This method detects for all other types of phones, +// but excludes the iPhone and RichCSS Tier devices. +// NOTE: This method probably won't work due to poor +// support for JavaScript among other devices. +function DetectTierOtherPhones() +{ + if (DetectMobileLong()) + { + //Exclude devices in the other 2 categories + if (DetectTierIphone() || DetectTierRichCss()) + return false; + + //Otherwise, it's a YES + else + return true; + } + else + return false; +}; + + +//************************** +// Initialize Key Stored Values. +function InitDeviceScan() +{ + //We'll use these 4 variables to speed other processing. They're super common. + isIphone = DetectIphoneOrIpod(); + isAndroidPhone = DetectAndroidPhone(); + isTierIphone = DetectTierIphone(); + isTierTablet = DetectTierTablet(); + + //Optional: Comment these out if you don't need them. + isTierRichCss = DetectTierRichCss(); + isTierGenericMobile = DetectTierOtherPhones(); +}; + +//Now, run the initialization method. +InitDeviceScan() diff --git a/core/main/handlers/modules/beefjs.rb b/core/main/handlers/modules/beefjs.rb index e0338d660..f120f7814 100644 --- a/core/main/handlers/modules/beefjs.rb +++ b/core/main/handlers/modules/beefjs.rb @@ -21,7 +21,7 @@ module BeEF beef_js_path = "#{$root_dir}/core/main/client/" # @note External libraries (like jQuery) that are not evaluated with Eruby and possibly not obfuscated - ext_js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js) + ext_js_sub_files = %w(lib/jquery-1.5.2.min.js lib/evercookie.js lib/json2.js lib/jools.min.js lib/mdetect.js) # @note BeEF libraries: need Eruby evaluation and obfuscation beef_js_sub_files = %w(beef.js browser.js browser/cookie.js browser/popup.js session.js os.js hardware.js dom.js logger.js net.js updater.js encode/base64.js encode/json.js net/local.js init.js mitb.js net/dns.js net/cors.js are.js) @@ -102,7 +102,7 @@ module BeEF if config.get("beef.extension.evasion.enable") evasion = BeEF::Extension::Evasion::Evasion.instance - @final_hook = ext_js_to_not_obfuscate + evasion.add_bootstrapper + evasion.obfuscate(ext_js_to_obfuscate + @hook) + @final_hook = ext_js_to_not_obfuscate + evasion.add_bootstrapper + evasion.obfuscate(ext_js_to_obfuscate + @hook) else @final_hook = ext_js_to_not_obfuscate + @hook end diff --git a/extensions/evasion/config.yaml b/extensions/evasion/config.yaml index 95536e9f4..06a1b803d 100644 --- a/extensions/evasion/config.yaml +++ b/extensions/evasion/config.yaml @@ -9,7 +9,7 @@ beef: enable: true name: 'Evasion' authors: ["antisnatchor"] - exclude_core_js: ["lib/jquery-1.5.2.min.js", "lib/json2.js", "lib/jools.min.js"] + exclude_core_js: ["lib/jquery-1.5.2.min.js", "lib/json2.js", "lib/jools.min.js","lib/mdetect.js"] scramble_variables: true scramble_cookies: true scramble: From da7a7b96033ae87ed07902e29966b7d29ab6f148 Mon Sep 17 00:00:00 2001 From: Nbblrr Date: Sat, 5 Jan 2013 20:43:28 +0100 Subject: [PATCH 2/2] Improved Hardware detection with mdetect 2. #722 --- core/main/client/browser.js | 92 ++++++------ core/main/client/hardware.js | 33 +--- core/main/client/lib/mdetect.js | 257 +------------------------------- 3 files changed, 52 insertions(+), 330 deletions(-) diff --git a/core/main/client/browser.js b/core/main/client/browser.js index f39fec33d..696601bd4 100644 --- a/core/main/client/browser.js +++ b/core/main/client/browser.js @@ -10,31 +10,31 @@ * Basic browser functions. */ beef.browser = { - + /** * Returns the user agent that the browser is claiming to be. * @example: beef.browser.getBrowserReportedName() */ - getBrowserReportedName: function() { + getBrowserReportedName: function() { return navigator.userAgent; }, - + /** * Returns true if IE6. * @example: beef.browser.isIE6() */ - isIE6: function() { + isIE6: function() { return !window.XMLHttpRequest && !window.globalStorage; }, - + /** * Returns true if IE7. * @example: beef.browser.isIE7() */ - isIE7: function() { + isIE7: function() { return !!window.XMLHttpRequest && !window.chrome && !window.opera && !window.getComputedStyle && !window.globalStorage && !document.documentMode; }, - + /** * Returns true if IE8. * @example: beef.browser.isIE8() @@ -42,7 +42,7 @@ beef.browser = { isIE8: function() { return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !window.performance; }, - + /** * Returns true if IE9. * @example: beef.browser.isIE9() @@ -50,7 +50,7 @@ beef.browser = { isIE9: function() { return !!window.XMLHttpRequest && !window.chrome && !window.opera && !!document.documentMode && !!window.XDomainRequest && !!window.performance; }, - + /** * * Returns true if IE10. @@ -68,7 +68,7 @@ beef.browser = { isIE: function() { return this.isIE6() || this.isIE7() || this.isIE8() || this.isIE9() || this.isIE10(); }, - + /** * Returns true if FF2. * @example: beef.browser.isFF2() @@ -76,7 +76,7 @@ beef.browser = { isFF2: function() { return !!window.globalStorage && !window.postMessage; }, - + /** * Returns true if FF3. * @example: beef.browser.isFF3() @@ -84,7 +84,7 @@ beef.browser = { isFF3: function() { return !!window.globalStorage && !!window.postMessage && !JSON.parse; }, - + /** * Returns true if FF3.5. * @example: beef.browser.isFF3_5() @@ -92,7 +92,7 @@ beef.browser = { isFF3_5: function() { return !!window.globalStorage && !!JSON.parse && !window.FileReader; }, - + /** * Returns true if FF3.6. * @example: beef.browser.isFF3_6() @@ -108,7 +108,7 @@ beef.browser = { isFF4: function() { return !!window.globalStorage && !!window.history.replaceState && window.navigator.userAgent.match(/Firefox\/4\./) != null; }, - + /** * Returns true if FF5. * @example: beef.browser.isFF5() @@ -228,7 +228,7 @@ beef.browser = { isS4: function() { return (window.navigator.userAgent.match(/ Version\/4\.\d/) != null && window.navigator.userAgent.match(/Safari\/\d/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window)); }, - + /** * Returns true if Safari 5.xx * @example: beef.browser.isS5() @@ -244,7 +244,7 @@ beef.browser = { isS6: function() { return (window.navigator.userAgent.match(/ Version\/6\.\d/) != null && window.navigator.userAgent.match(/Safari\/\d/) != null && !window.globalStorage && !!window.getComputedStyle && !window.opera && !window.chrome && !("MozWebSocket" in window)); }, - + /** * Returns true if Safari. * @example: beef.browser.isS() @@ -260,7 +260,7 @@ beef.browser = { isC5: function() { return (!!window.chrome && !window.webkitPerformance) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10)==5)?true:false); }, - + /** * Returns true if Chrome 6. * @example: beef.browser.isC6() @@ -284,7 +284,7 @@ beef.browser = { isC8: function() { return (!!window.chrome && !!window.webkitPerformance) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10)==8)?true:false); }, - + /** * Returns true if Chrome 9. * @example: beef.browser.isC9() @@ -292,7 +292,7 @@ beef.browser = { isC9: function() { return (!!window.chrome && !!window.webkitPerformance) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10)==9)?true:false); }, - + /** * Returns true if Chrome 10. * @example: beef.browser.isC10() @@ -308,7 +308,7 @@ beef.browser = { isC11: function() { return (!!window.chrome && !window.webkitPerformance) && ((parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10)==11)?true:false); }, - + /** * Returns true if Chrome 12. * @example: beef.browser.isC12() @@ -460,7 +460,7 @@ beef.browser = { isO: function() { return this.isO9_52() || this.isO9_60() || this.isO10() || this.isO11() || this.isO12(); }, - + /** * Returns the type of browser being used. * @example: beef.browser.type().IE6 @@ -468,7 +468,7 @@ beef.browser = { * @example: beef.browser.type().O */ type: function() { - + return { C5: this.isC5(), // Chrome 5 C6: this.isC6(), // Chrome 6 @@ -531,7 +531,7 @@ beef.browser = { S: this.isS() // Safari any version } }, - + /** * Returns the type of browser being used. * @return: {String} User agent software and version. @@ -539,7 +539,7 @@ beef.browser = { * @example: beef.browser.getBrowserVersion() */ getBrowserVersion: function() { - + if (this.isC5()) { return '5' }; // Chrome 5 if (this.isC6()) { return '6' }; // Chrome 6 if (this.isC7()) { return '7' }; // Chrome 7 @@ -597,7 +597,7 @@ beef.browser = { return 'UNKNOWN'; // Unknown UA }, - + /** * Returns the type of user agent by hooked browser. * @return: {String} User agent software. @@ -605,7 +605,7 @@ beef.browser = { * @example: beef.browser.getBrowserName() */ getBrowserName: function() { - + if (this.isC()) { return 'C' }; // Chrome any version if (this.isFF()) { return 'FF'}; // Firefox any version if (this.isIE()) { return 'IE'}; // Internet Explorer any version @@ -613,7 +613,7 @@ beef.browser = { if (this.isS()) { return 'S' }; // Safari any version return 'UN'; // Unknown UA }, - + /** * Checks if the zombie has flash installed and enabled. * @return: {Boolean} true or false. @@ -622,7 +622,7 @@ beef.browser = { */ hasFlash: function() { if (!this.type().IE) { - return (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]); + return (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]); } else { flash_versions = 11; flash_installed = false; @@ -683,7 +683,7 @@ beef.browser = { */ hasCors: function() { if ('withCredentials' in new XMLHttpRequest()) - return true; + return true; else if (typeof XDomainRequest !== "undefined") return true; else @@ -726,7 +726,7 @@ beef.browser = { return false; } }, - + /** * Checks if the zombie has VBScript enabled. * @return: {Boolean} true or false. @@ -740,7 +740,7 @@ beef.browser = { return false; } }, - + /** * Returns the list of plugins installed in the browser. */ @@ -778,20 +778,20 @@ beef.browser = { // Return results return results; }, - + /** * Returns a list of plugins detected by IE. This is a hack because IE doesn't - * support navigator.plugins + * support navigator.plugins */ getPluginsIE: function() { var results = ''; var plugins = {'AdobePDF6':{ - 'control':'PDF.PdfCtrl', + 'control':'PDF.PdfCtrl', 'return': function(control) { version = control.getVersions().split(','); version = version[0].split('='); return 'Acrobat Reader v'+parseFloat(version[1]); - }}, + }}, 'AdobePDF7':{ 'control':'AcroPDF.PDF', 'return': function(control) { @@ -851,10 +851,10 @@ beef.browser = { /** * Returns zombie screen size and color depth. - */ + */ getScreenSize: function() { return { - width: window.screen.width, + width: window.screen.width, height: window.screen.height, colordepth: window.screen.colorDepth } @@ -863,7 +863,7 @@ beef.browser = { /** * Returns zombie browser window size. * @from: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow - */ + */ getWindowSize: function() { var myWidth = 0, myHeight = 0; if( typeof( window.innerWidth ) == 'number' ) { @@ -884,13 +884,13 @@ beef.browser = { height: myHeight } }, - + /** * Construct hash from browser details. This function is used to grab the browser details during the hooking process - */ + */ getDetails: function() { var details = new Array(); - + var browser_name = beef.browser.getBrowserName(); var browser_version = beef.browser.getBrowserVersion(); var browser_reported_name = beef.browser.getBrowserReportedName(); @@ -903,7 +903,7 @@ beef.browser = { var browser_plugins = beef.browser.getPlugins(); var date_stamp = new Date().toString(); var os_name = beef.os.getName(); - var hw_name = beef.hardware.getName(); + var hw_name = beef.hardware.getMobileName(); var system_platform = (typeof(navigator.platform) != "undefined" && navigator.platform != "") ? navigator.platform : null; var browser_type = JSON.stringify(beef.browser.type(), function (key, value) {if (value == true) return value; else if (typeof value == 'object') return value; else return;}); var screen_size = beef.browser.getScreenSize(); @@ -947,7 +947,7 @@ beef.browser = { return details; }, - + /** * Returns array of results, whether or not the target zombie has visited the specified URL */ @@ -970,7 +970,7 @@ beef.browser = { a.href = u; ifdoc.body.appendChild(a); var width = null; - (a.currentStyle) ? width = a.currentStyle['width'] : width = ifdoc.defaultView.getComputedStyle(a, null).getPropertyValue("width"); + (a.currentStyle) ? width = a.currentStyle['width'] : width = ifdoc.defaultView.getComputedStyle(a, null).getPropertyValue("width"); if (width == '0px') { success = true; } @@ -979,7 +979,7 @@ beef.browser = { } } beef.dom.removeElement(iframe); - if (results.length == 0) + if (results.length == 0) { return false; } @@ -1136,7 +1136,7 @@ beef.browser = { return deferredObject.promise(); } - + }; beef.regCmp('beef.browser'); diff --git a/core/main/client/hardware.js b/core/main/client/hardware.js index 01f69dc50..32732e5ec 100644 --- a/core/main/client/hardware.js +++ b/core/main/client/hardware.js @@ -8,38 +8,14 @@ beef.hardware = { ua: navigator.userAgent, - isWinPhone: function() { - return (this.ua.match('(Windows Phone)')) ? true : false; - }, - - isIphone: function() { - return (this.ua.indexOf('iPhone') != -1) ? true : false; - }, - - isIpad: function() { - return (this.ua.indexOf('iPad') != -1) ? true : false; - }, - - isIpod: function() { - return (this.ua.indexOf('iPod') != -1) ? true : false; - }, - isNokia: function() { return (this.ua.match('(Maemo Browser)|(Symbian)|(Nokia)')) ? true : false; }, - isBlackBerry: function() { - return (this.ua.match('BlackBerry')) ? true : false; - }, - isZune: function() { return (this.ua.match('ZuneWP7')) ? true : false; }, - isKindle: function() { - return (this.ua.match('Kindle')) ? true : false; - }, - isHtc: function() { return (this.ua.match('HTC')) ? true : false; }, @@ -66,15 +42,15 @@ beef.hardware = { return DetectMobileQuick(); }, - getName: function() { - var ua = navigator.userAgent; + getMobileName: function() { + var ua = navigator.userAgent.toLowerCase(); if(DetectIphone()) { return "iPhone"}; if(DetectIpod()) { return "iPod Touch"}; if(DetectIpad()) { return "iPad"}; if (this.isHtc()) { return 'HTC'}; if (this.isMotorola()) { return 'Motorola'}; if (this.isZune()) { return 'Zune'}; - if (this.isGoogle()) { return 'Google'}; + if (this.isGoogle()) { return 'Google Nexus One'}; if (this.isEricsson()) { return 'Ericsson'}; if(DetectAndroidPhone()) { return "Android Phone"}; if(DetectAndroidTablet()) { return "Android Tablet"}; @@ -82,7 +58,8 @@ beef.hardware = { if(ua.search(deviceS60) > -1) { return "Nokia S60"}; if(ua.search(deviceS70) > -1) { return "Nokia S70"}; if(ua.search(deviceS80) > -1) { return "Nokia S80"}; - if(ua.search(deviceS90) > -1) { return "Nokia Symbian"}; + if(ua.search(deviceS90) > -1) { return "Nokia S90"}; + if(ua.search(deviceSymbian) > -1) { return "Nokia Symbian"}; if (this.isNokia()) { return 'Nokia'}; if(DetectWindowsPhone7()) { return "Windows Phone 7"}; if(DetectWindowsMobile()) { return "Windows Mobile"}; diff --git a/core/main/client/lib/mdetect.js b/core/main/client/lib/mdetect.js index 85de2b29e..8fa1ad199 100644 --- a/core/main/client/lib/mdetect.js +++ b/core/main/client/lib/mdetect.js @@ -1,39 +1,7 @@ /* ******************************************* // Copyright 2010-2012, Anthony Hand -// -// File version date: April 23, 2012 -// Update: -// - Updated DetectAmazonSilk(): Fixed an issue in the detection logic. -// -// File version date: April 22, 2012 - Second update -// Update: To address additional Kindle issues... -// - Updated DetectRichCSS(): Excluded e-Ink Kindle devices. -// - Created DetectAmazonSilk(): Created to detect Kindle Fire devices in Silk mode. -// - Updated DetectMobileQuick(): Updated to include e-Ink Kindle devices and the Kindle Fire in Silk mode. -// -// File version date: April 11, 2012 -// Update: -// - Added a new variable for the new BlackBerry Curve Touch (9380): deviceBBCurveTouch. -// - Updated DetectBlackBerryTouch() to support the new BlackBerry Curve Touch (9380). -// -// File version date: January 21, 2012 -// Update: -// - Moved Windows Phone 7 to the iPhone Tier. WP7.5's IE 9-based browser is good enough now. -// - Added a new variable for 2 versions of the new BlackBerry Bold Touch (9900 and 9930): deviceBBBoldTouch. -// - Updated DetectBlackBerryTouch() to support the 2 versions of the new BlackBerry Bold Touch (9900 and 9930). -// - Updated DetectKindle() to focus on eInk devices only. The Kindle Fire should be detected as a regular Android device. -// -// File version date: August 22, 2011 -// Update: -// - Updated DetectAndroidTablet() to fix a bug introduced in the last fix! The true/false returns were mixed up. -// -// File version date: August 16, 2011 -// Update: -// - Updated DetectAndroidTablet() to exclude Opera Mini, which was falsely reporting as running on a tablet device when on a phone. -// - Updated the user agent (uagent) init technique to handle spiders and such with null values. -// -// +// mdetect : http://code.google.com/p/mobileesp/source/browse/JavaScript/mdetect.js r215 // LICENSE INFORMATION // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -44,49 +12,16 @@ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, // either express or implied. See the License for the specific // language governing permissions and limitations under the License. -// -// -// ABOUT THIS PROJECT -// Project Owner: Anthony Hand -// Email: anthony.hand@gmail.com -// Web Site: http://www.mobileesp.com -// Source Files: http://code.google.com/p/mobileesp/ -// -// Versions of this code are available for: -// PHP, JavaScript, Java, ASP.NET (C#), and Ruby -// -// -// WARNING: -// These JavaScript-based device detection features may ONLY work -// for the newest generation of smartphones, such as the iPhone, -// Android and Palm WebOS devices. -// These device detection features may NOT work for older smartphones -// which had poor support for JavaScript, including -// older BlackBerry, PalmOS, and Windows Mobile devices. -// Additionally, because JavaScript support is extremely poor among -// 'feature phones', these features may not work at all on such devices. -// For better results, consider using a server-based version of this code, -// such as Java, APS.NET, PHP, or Ruby. -// // ******************************************* */ -//Optional: Store values for quickly accessing same info multiple times. -//Note: These values are not set automatically. -//Stores whether the device is an iPhone or iPod Touch. var isIphone = false; -//Stores whether the device is an Android phone or multi-media player. var isAndroidPhone = false; -//Stores whether is the Tablet (HTML5-capable, larger screen) tier of devices. var isTierTablet = false; -//Stores whether is the iPhone tier of devices. var isTierIphone = false; -//Stores whether the device can probably support Rich CSS, but JavaScript support is not assumed. (e.g., newer BlackBerry, Windows Mobile) var isTierRichCss = false; -//Stores whether it is another mobile device, which cannot be assumed to support CSS or JS (eg, older BlackBerry, RAZR) var isTierGenericMobile = false; -//Initialize some initial string variables we'll look for later. var engineWebKit = "webkit"; var deviceIphone = "iphone"; var deviceIpod = "ipod"; @@ -134,12 +69,9 @@ var engineXiino = "xiino"; var deviceKindle = "kindle"; //Amazon Kindle, eInk one var engineSilk = "silk"; //Amazon's accelerated Silk browser for Kindle Fire -//Initialize variables for mobile-specific content. var vndwap = "vnd.wap"; var wml = "wml"; -//Initialize variables for random devices and mobile browsers. -//Some of these may not support JavaScript var deviceTablet = "tablet"; //Generic term for slate and tablet devices var deviceBrew = "brew"; var deviceDanger = "danger"; @@ -164,45 +96,33 @@ var mini = "mini"; //Some mobile browsers put 'mini' in their names. var mobile = "mobile"; //Some mobile browsers put 'mobile' in their user agent strings. var mobi = "mobi"; //Some mobile browsers put 'mobi' in their user agent strings. -//Use Maemo, Tablet, and Linux to test for Nokia's Internet Tablets. var maemo = "maemo"; var linux = "linux"; var qtembedded = "qt embedded"; //for Sony Mylo and others var mylocom2 = "com2"; //for Sony Mylo also -//In some UserAgents, the only clue is the manufacturer. var manuSonyEricsson = "sonyericsson"; var manuericsson = "ericsson"; var manuSamsung1 = "sec-sgh"; var manuSony = "sony"; var manuHtc = "htc"; //Popular Android and WinMo manufacturer -//In some UserAgents, the only clue is the operator. var svcDocomo = "docomo"; var svcKddi = "kddi"; var svcVodafone = "vodafone"; -//Disambiguation strings. var disUpdate = "update"; //pda vs. update - - -//Initialize our user agent string. var uagent = ""; if (navigator && navigator.userAgent) uagent = navigator.userAgent.toLowerCase(); - -//************************** -// Detects if the current device is an iPhone. function DetectIphone() { if (uagent.search(deviceIphone) > -1) { - //The iPad and iPod Touch say they're an iPhone! So let's disambiguate. if (DetectIpad() || DetectIpod()) return false; - //Yay! It's an iPhone! else return true; } @@ -210,8 +130,6 @@ function DetectIphone() return false; } -//************************** -// Detects if the current device is an iPod Touch. function DetectIpod() { if (uagent.search(deviceIpod) > -1) @@ -220,8 +138,6 @@ function DetectIpod() return false; } -//************************** -// Detects if the current device is an iPad tablet. function DetectIpad() { if (uagent.search(deviceIpad) > -1 && DetectWebkit()) @@ -230,12 +146,8 @@ function DetectIpad() return false; } -//************************** -// Detects if the current device is an iPhone or iPod Touch. function DetectIphoneOrIpod() { - //We repeat the searches here because some iPods - // may report themselves as an iPhone, which is ok. if (uagent.search(deviceIphone) > -1 || uagent.search(deviceIpod) > -1) return true; @@ -243,8 +155,6 @@ function DetectIphoneOrIpod() return false; } -//************************** -// Detects *any* iOS device: iPhone, iPod Touch, iPad. function DetectIos() { if (DetectIphoneOrIpod() || DetectIpad()) @@ -253,56 +163,38 @@ function DetectIos() return false; } -//************************** -// Detects *any* Android OS-based device: phone, tablet, and multi-media player. -// Also detects Google TV. function DetectAndroid() { if ((uagent.search(deviceAndroid) > -1) || DetectGoogleTV()) return true; - //Special check for the HTC Flyer 7" tablet. It should report here. if (uagent.search(deviceHtcFlyer) > -1) return true; else return false; } -//************************** -// Detects if the current device is a (small-ish) Android OS-based device -// used for calling and/or multi-media (like a Samsung Galaxy Player). -// Google says these devices will have 'Android' AND 'mobile' in user agent. -// Ignores tablets (Honeycomb and later). function DetectAndroidPhone() { if (DetectAndroid() && (uagent.search(mobile) > -1)) return true; - //Special check for Android phones with Opera Mobile. They should report here. if (DetectOperaAndroidPhone()) return true; - //Special check for the HTC Flyer 7" tablet. It should report here. if (uagent.search(deviceHtcFlyer) > -1) return true; else return false; } -//************************** -// Detects if the current device is a (self-reported) Android tablet. -// Google says these devices will have 'Android' and NOT 'mobile' in their user agent. function DetectAndroidTablet() { - //First, let's make sure we're on an Android device. if (!DetectAndroid()) return false; - //Special check for Opera Android Phones. They should NOT report here. if (DetectOperaMobile()) return false; - //Special check for the HTC Flyer 7" tablet. It should NOT report here. if (uagent.search(deviceHtcFlyer) > -1) return false; - //Otherwise, if it's Android and does NOT have 'mobile' in it, Google says it's a tablet. if (uagent.search(mobile) > -1) return false; else @@ -310,9 +202,6 @@ function DetectAndroidTablet() } -//************************** -// Detects if the current device is an Android OS-based device and -// the browser is based on WebKit. function DetectAndroidWebKit() { if (DetectAndroid() && DetectWebkit()) @@ -322,8 +211,6 @@ function DetectAndroidWebKit() } -//************************** -// Detects if the current device is a GoogleTV. function DetectGoogleTV() { if (uagent.search(deviceGoogleTV) > -1) @@ -333,8 +220,6 @@ function DetectGoogleTV() } -//************************** -// Detects if the current browser is based on WebKit. function DetectWebkit() { if (uagent.search(engineWebKit) > -1) @@ -343,8 +228,6 @@ function DetectWebkit() return false; } -//************************** -// Detects if the current browser is the Nokia S60 Open Source Browser. function DetectS60OssBrowser() { if (DetectWebkit()) @@ -359,10 +242,6 @@ function DetectS60OssBrowser() return false; } -//************************** -// Detects if the current device is any Symbian OS-based device, -// including older S60, Series 70, Series 80, Series 90, and UIQ, -// or other browsers running on these devices. function DetectSymbianOS() { if (uagent.search(deviceSymbian) > -1 || @@ -375,9 +254,6 @@ function DetectSymbianOS() return false; } -//************************** -// Detects if the current browser is a -// Windows Phone 7 device. function DetectWindowsPhone7() { if (uagent.search(deviceWinPhone7) > -1) @@ -386,26 +262,17 @@ function DetectWindowsPhone7() return false; } -//************************** -// Detects if the current browser is a Windows Mobile device. -// Excludes Windows Phone 7 devices. -// Focuses on Windows Mobile 6.xx and earlier. function DetectWindowsMobile() { - //Exclude new Windows Phone 7. if (DetectWindowsPhone7()) return false; - //Most devices use 'Windows CE', but some report 'iemobile' - // and some older ones report as 'PIE' for Pocket IE. if (uagent.search(deviceWinMob) > -1 || uagent.search(deviceIeMob) > -1 || uagent.search(enginePie) > -1) return true; - //Test for Windows Mobile PPC but not old Macintosh PowerPC. if ((uagent.search(devicePpc) > -1) && !(uagent.search(deviceMacPpc) > -1)) return true; - //Test for Windwos Mobile-based HTC devices. if (uagent.search(manuHtc) > -1 && uagent.search(deviceWindows) > -1) return true; @@ -413,9 +280,6 @@ function DetectWindowsMobile() return false; } -//************************** -// Detects if the current browser is a BlackBerry of some sort. -// Includes the PlayBook. function DetectBlackBerry() { if (uagent.search(deviceBB) > -1) @@ -426,9 +290,6 @@ function DetectBlackBerry() return false; } -//************************** -// Detects if the current browser is on a BlackBerry tablet device. -// Example: PlayBook function DetectBlackBerryTablet() { if (uagent.search(deviceBBPlaybook) > -1) @@ -437,10 +298,6 @@ function DetectBlackBerryTablet() return false; } -//************************** -// Detects if the current browser is a BlackBerry device AND uses a -// WebKit-based browser. These are signatures for the new BlackBerry OS 6. -// Examples: Torch. Includes the Playbook. function DetectBlackBerryWebKit() { if (DetectBlackBerry() && @@ -450,9 +307,6 @@ function DetectBlackBerryWebKit() return false; } -//************************** -// Detects if the current browser is a BlackBerry Touch -// device, such as the Storm, Torch, and Bold Touch. Excludes the Playbook. function DetectBlackBerryTouch() { if (DetectBlackBerry() && @@ -465,14 +319,8 @@ function DetectBlackBerryTouch() return false; } -//************************** -// Detects if the current browser is a BlackBerry OS 5 device AND -// has a more capable recent browser. Excludes the Playbook. -// Examples, Storm, Bold, Tour, Curve2 -// Excludes the new BlackBerry OS 6 and 7 browser!! function DetectBlackBerryHigh() { - //Disambiguate for BlackBerry OS 6 or 7 (WebKit) browser if (DetectBlackBerryWebKit()) return false; if (DetectBlackBerry()) @@ -489,15 +337,10 @@ function DetectBlackBerryHigh() return false; } -//************************** -// Detects if the current browser is a BlackBerry device AND -// has an older, less capable browser. -// Examples: Pearl, 8800, Curve1. function DetectBlackBerryLow() { if (DetectBlackBerry()) { - //Assume that if it's not in the High tier or has WebKit, then it's Low. if (DetectBlackBerryHigh() || DetectBlackBerryWebKit()) return false; else @@ -508,17 +351,12 @@ function DetectBlackBerryLow() } -//************************** -// Detects if the current browser is on a PalmOS device. function DetectPalmOS() { - //Most devices nowadays report as 'Palm', - // but some older ones reported as Blazer or Xiino. if (uagent.search(devicePalm) > -1 || uagent.search(engineBlazer) > -1 || uagent.search(engineXiino) > -1) { - //Make sure it's not WebOS first if (DetectPalmWebOS()) return false; else @@ -528,9 +366,6 @@ function DetectPalmOS() return false; } -//************************** -// Detects if the current browser is on a Palm device -// running the new WebOS. function DetectPalmWebOS() { if (uagent.search(deviceWebOS) > -1) @@ -539,8 +374,6 @@ function DetectPalmWebOS() return false; } -//************************** -// Detects if the current browser is on an HP tablet running WebOS. function DetectWebOSTablet() { if (uagent.search(deviceWebOShp) > -1 && @@ -550,9 +383,6 @@ function DetectWebOSTablet() return false; } -//************************** -// Detects if the current browser is a -// Garmin Nuvifone. function DetectGarminNuvifone() { if (uagent.search(deviceNuvifone) > -1) @@ -562,10 +392,6 @@ function DetectGarminNuvifone() } -//************************** -// Check to see whether the device is a 'smartphone'. -// You might wish to send smartphones to a more capable web page -// than a dumbed down WAP page. function DetectSmartphone() { if (DetectIphoneOrIpod() @@ -580,12 +406,9 @@ function DetectSmartphone() || DetectGarminNuvifone()) return true; - //Otherwise, return false. return false; }; -//************************** -// Detects if the current device is an Archos media player/Internet tablet. function DetectArchos() { if (uagent.search(deviceArchos) > -1) @@ -594,8 +417,6 @@ function DetectArchos() return false; } -//************************** -// Detects whether the device is a Brew-powered device. function DetectBrewDevice() { if (uagent.search(deviceBrew) > -1) @@ -604,8 +425,6 @@ function DetectBrewDevice() return false; } -//************************** -// Detects the Danger Hiptop device. function DetectDangerHiptop() { if (uagent.search(deviceDanger) > -1 || @@ -615,14 +434,10 @@ function DetectDangerHiptop() return false; } -//************************** -// Detects if the current device is on one of -// the Maemo-based Nokia Internet Tablets. function DetectMaemoTablet() { if (uagent.search(maemo) > -1) return true; - //For Nokia N810, must be Linux + Tablet, or else it could be something else. if ((uagent.search(linux) > -1) && (uagent.search(deviceTablet) > -1) && !DetectWebOSTablet() @@ -632,8 +447,6 @@ function DetectMaemoTablet() return false; } -//************************** -// Detects if the current browser is a Sony Mylo device. function DetectSonyMylo() { if (uagent.search(manuSony) > -1) @@ -648,8 +461,6 @@ function DetectSonyMylo() return false; } -//************************** -// Detects if the current browser is Opera Mobile or Mini. function DetectOperaMobile() { if (uagent.search(engineOpera) > -1) @@ -664,9 +475,6 @@ function DetectOperaMobile() return false; } -//************************** -// Detects if the current browser is Opera Mobile -// running on an Android phone. function DetectOperaAndroidPhone() { if ((uagent.search(engineOpera) > -1) && @@ -677,9 +485,6 @@ function DetectOperaAndroidPhone() return false; } -//************************** -// Detects if the current browser is Opera Mobile -// running on an Android tablet. function DetectOperaAndroidTablet() { if ((uagent.search(engineOpera) > -1) && @@ -690,8 +495,6 @@ function DetectOperaAndroidTablet() return false; } -//************************** -// Detects if the current device is a Sony Playstation. function DetectSonyPlaystation() { if (uagent.search(devicePlaystation) > -1) @@ -700,8 +503,6 @@ function DetectSonyPlaystation() return false; }; -//************************** -// Detects if the current device is a Nintendo game device. function DetectNintendo() { if (uagent.search(deviceNintendo) > -1 || @@ -712,8 +513,6 @@ function DetectNintendo() return false; }; -//************************** -// Detects if the current device is a Microsoft Xbox. function DetectXbox() { if (uagent.search(deviceXbox) > -1) @@ -722,8 +521,6 @@ function DetectXbox() return false; }; -//************************** -// Detects if the current device is an Internet-capable game console. function DetectGameConsole() { if (DetectSonyPlaystation()) @@ -736,9 +533,6 @@ function DetectGameConsole() return false; }; -//************************** -// Detects if the current device is an Amazon Kindle (eInk devices only). -// Note: For the Kindle Fire, use the normal Android methods. function DetectKindle() { if (uagent.search(deviceKindle) > -1 && @@ -748,9 +542,6 @@ function DetectKindle() return false; } -//************************** -// Detects if the current Amazon device is using the Silk Browser. -// Note: Typically used by the the Kindle Fire. function DetectAmazonSilk() { if (uagent.search(engineSilk) > -1) @@ -759,17 +550,11 @@ function DetectAmazonSilk() return false; } -//************************** -// Detects if the current device is a mobile device. -// This method catches most of the popular modern devices. -// Excludes Apple iPads and other modern tablets. function DetectMobileQuick() { - //Let's exclude tablets. if (DetectTierTablet()) return false; - //Most mobile browsing is done on smartphones if (DetectSmartphone()) return true; @@ -809,8 +594,6 @@ function DetectMobileQuick() }; -//************************** -// Detects in a more comprehensive way if the current device is a mobile device. function DetectMobileLong() { if (DetectMobileQuick()) @@ -820,7 +603,6 @@ function DetectMobileLong() if (DetectSonyMylo()) return true; - //Detect for certain very old devices with stupid useragent strings. if (uagent.search(manuSamsung1) > -1 || uagent.search(manuSonyEricsson) > -1 || uagent.search(manuericsson) > -1) @@ -838,15 +620,6 @@ function DetectMobileLong() }; -//***************************** -// For Mobile Web Site Design -//***************************** - -//************************** -// The quick way to detect for a tier of devices. -// This method detects for the new generation of -// HTML 5 capable, larger screen tablets. -// Includes iPad, Android (e.g., Xoom), BB Playbook, WebOS, etc. function DetectTierTablet() { if (DetectIpad() @@ -858,11 +631,6 @@ function DetectTierTablet() return false; }; -//************************** -// The quick way to detect for a tier of devices. -// This method detects for devices which can -// display iPhone-optimized web content. -// Includes iPhone, iPod Touch, Android, Windows Phone 7, WebOS, etc. function DetectTierIphone() { if (DetectIphoneOrIpod()) @@ -881,31 +649,21 @@ function DetectTierIphone() return false; }; -//************************** -// The quick way to detect for a tier of devices. -// This method detects for devices which are likely to be -// capable of viewing CSS content optimized for the iPhone, -// but may not necessarily support JavaScript. -// Excludes all iPhone Tier devices. function DetectTierRichCss() { if (DetectMobileQuick()) { - //Exclude iPhone Tier and e-Ink Kindle devices if (DetectTierIphone() || DetectKindle()) return false; - //The following devices are explicitly ok. if (DetectWebkit()) return true; if (DetectS60OssBrowser()) return true; - //Note: 'High' BlackBerry devices ONLY if (DetectBlackBerryHigh()) return true; - //Older Windows 'Mobile' isn't good enough for iPhone Tier. if (DetectWindowsMobile()) return true; @@ -919,21 +677,13 @@ function DetectTierRichCss() return false; }; -//************************** -// The quick way to detect for a tier of devices. -// This method detects for all other types of phones, -// but excludes the iPhone and RichCSS Tier devices. -// NOTE: This method probably won't work due to poor -// support for JavaScript among other devices. function DetectTierOtherPhones() { if (DetectMobileLong()) { - //Exclude devices in the other 2 categories if (DetectTierIphone() || DetectTierRichCss()) return false; - //Otherwise, it's a YES else return true; } @@ -942,20 +692,15 @@ function DetectTierOtherPhones() }; -//************************** -// Initialize Key Stored Values. function InitDeviceScan() { - //We'll use these 4 variables to speed other processing. They're super common. isIphone = DetectIphoneOrIpod(); isAndroidPhone = DetectAndroidPhone(); isTierIphone = DetectTierIphone(); isTierTablet = DetectTierTablet(); - //Optional: Comment these out if you don't need them. isTierRichCss = DetectTierRichCss(); isTierGenericMobile = DetectTierOtherPhones(); }; -//Now, run the initialization method. InitDeviceScan()