Skip to content

Commit

Permalink
fix issues #33, #35
Browse files Browse the repository at this point in the history
  • Loading branch information
kkoooqq committed Dec 27, 2021
1 parent 16e0294 commit 582df95
Show file tree
Hide file tree
Showing 7 changed files with 3,558 additions and 3,098 deletions.
6,397 changes: 3,395 additions & 3,002 deletions device-hub-demo/iPhone.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fakebrowser",
"version": "0.0.62",
"version": "0.0.63",
"description": "🤖 Fake fingerprints to bypass anti-bot systems. Simulate mouse and keyboard operations to make behavior like a real person.",
"repository": {
"type": "git",
Expand Down
78 changes: 42 additions & 36 deletions src/core/DeviceDescriptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,104 +234,110 @@ export default class DeviceDescriptorHelper {

/**
* Check device descriptor legal based on attributes
* @param e
* @param dd
*/
static checkLegal(e: DeviceDescriptor): boolean {
if (!e) {
static checkLegal(dd: DeviceDescriptor): boolean {
if (!dd) {
throw new Error('DeviceDescriptor empty')
}

if (!e.navigator) {
if (!dd.navigator) {
throw new Error('navigator empty')
}

if (!UserAgentHelper.isMobile(e.navigator.userAgent)) {
if (!UserAgentHelper.isMobile(dd.navigator.userAgent)) {
// If not mobile phone, but screen is too small, filter it out
if (e.window.innerWidth < 900 || e.window.innerHeight < 450) {
if (dd.window.innerWidth < 900 || dd.window.innerHeight < 450) {
throw new Error('width and height of windows is too small')
}

// Screen height greater than width, remove it
if (e.window.innerHeight > e.window.innerWidth) {
if (dd.window.innerHeight > dd.window.innerWidth) {
throw new Error('Height of window is greater than width of window, non-normal browser')
}

if (dd.window.innerHeight > dd.screen.availHeight
|| dd.window.innerWidth > dd.screen.availWidth) {

throw new Error('Width of browser window cannot be greater than width of screen and height cannot be greater than height of screen')
}

// No plugins and mineType information, remove
// noinspection RedundantIfStatementJS
if (!e.plugins || !e.plugins.mimeTypes.length || !e.plugins.plugins.length) {
if (!dd.plugins || !dd.plugins.mimeTypes.length || !dd.plugins.plugins.length) {
throw new Error('Plugins of desktop browser cannot be empty')
}

// Ordinary PC computers should not have touch screens
if (e.navigator.maxTouchPoints != 0) {
if (dd.navigator.maxTouchPoints != 0) {
throw new Error('Desktop browsers cannot have touchscreens')
}

// mimeTypes
if (!dd.mimeTypes || !dd.mimeTypes.length) {
throw new Error('mimeTypes cannot be empty')
}

// permissions
if (!dd.permissions || Object.keys(dd.permissions).length === 0) {
throw new Error('permissions cannot be empty')
}
} else {
if (e.navigator.maxTouchPoints === 0) {
if (dd.navigator.maxTouchPoints === 0) {
throw new Error('Mobile devices must have touch screen')
}
}

assert(dd.navigator.userAgent, 'userAgent cannot be empty')
const lowerCaseUserAgent = dd.navigator.userAgent.toLowerCase()

if (
!e.navigator.language
|| !e.navigator.languages
|| !e.navigator.languages.length
!dd.navigator.language
|| !dd.navigator.languages
|| !dd.navigator.languages.length
) {
throw new Error('language cannot be empty')
}

if (e.window.innerHeight > e.screen.availHeight
|| e.window.innerWidth > e.screen.availWidth) {

throw new Error('Width of browser window cannot be greater than width of screen and height cannot be greater than height of screen')
}

// if (e.window.screenX != 0 || e.window.screenY != 0) {
// return false
// }

// Only chrome browser is allowed
if (!e.navigator.userAgent.toLowerCase().includes('chrome')) {
if (
!lowerCaseUserAgent.includes('chrome')
&& !lowerCaseUserAgent.includes('crios')
) {
throw new Error('Only chrome kernel browsers are supported')
}

// chrome os
if (e.navigator.userAgent.toLowerCase().includes('cros')) {
if (lowerCaseUserAgent.includes('cros')) {
throw new Error('ChromeOS is not supported')
}

// Googlebot
if (e.navigator.userAgent.toLowerCase().includes('googlebot')) {
if (lowerCaseUserAgent.includes('googlebot')) {
throw new Error('google bot')
}
if (e.navigator.userAgent.toLowerCase().includes('adsbot-google')) {
if (lowerCaseUserAgent.includes('adsbot-google')) {
throw new Error('google bot')
}

if (e.navigator.userAgent.toLowerCase().includes('mediapartners')) {
if (lowerCaseUserAgent.includes('mediapartners')) {
throw new Error('google bot')
}

// Chrome-Lighthouse
if (e.navigator.userAgent.toLowerCase().includes('chrome-lighthouse')) {
if (lowerCaseUserAgent.includes('chrome-lighthouse')) {
throw new Error('google bot')
}

// voices
if (!e.voices || !e.voices.length) {
if (!dd.voices || !dd.voices.length) {
throw new Error('voices cannot be empty')
}

// mimeTypes
if (!e.mimeTypes || !e.mimeTypes.length) {
throw new Error('mimeTypes cannot be empty')
}

// permissions
if (!e.permissions || Object.keys(e.permissions).length === 0) {
throw new Error('permissions cannot be empty')
}

return true
}

Expand Down
3 changes: 2 additions & 1 deletion src/core/FakeBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,10 +354,11 @@ export class FakeBrowser {
)
}

const pagesFn = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this.vanillaBrowser), 'pages')!.value.bind(this.vanillaBrowser)
Object.defineProperty(Object.getPrototypeOf(this.vanillaBrowser), 'pages', {
value: new Proxy(this.vanillaBrowser.pages, {
async apply(target, thisArg, args) {
let pages: Page[] = await Reflect.apply(target, thisArg, args)
let pages: Page[] = await pagesFn()

// Maybe browser is created based on connect, with different instances
// so can only compare TargetId
Expand Down
4 changes: 2 additions & 2 deletions src/core/UserAgentHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function browserType(userAgent: string): BrowserTypes {
}

function chromeMajorVersion(userAgent: string): number | null {
const chromeVersionPart = userAgent.match(/Chrome\/(.*?)\./)
const chromeVersionPart = userAgent.match(/[Chrome|CriOS]\/(.*?)\./)
if (chromeVersionPart) {
return parseInt(chromeVersionPart[1])
}
Expand All @@ -54,7 +54,7 @@ function chromeMajorVersion(userAgent: string): number | null {
}

function chromeVersion(userAgent: string): string | null {
const chromeVersionPart = userAgent.match(/Chrome\/(.*?) /)
const chromeVersionPart = userAgent.match(/[Chrome|CriOS]\/(.*?) /)
if (chromeVersionPart) {
return chromeVersionPart[1]
}
Expand Down
66 changes: 54 additions & 12 deletions src/plugins/evasions/_utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -664,25 +664,36 @@ utils.replaceWithProxy = (obj, propName, handler) => {
* @param {object} handler - The JS Proxy handler to use
*/
utils.replaceGetterWithProxy = (obj, propName, handler) => {
const fn = utils.cache.Object.getOwnPropertyDescriptor(obj, propName).get;
const fnStr = fn.toString(); // special getter function string
const proxyObj = utils.newProxyInstance(fn, utils.stripProxyFromErrors(handler));
const desc = utils.cache.Object.getOwnPropertyDescriptor(obj, propName)
if (desc) {
const fn = utils.cache.Object.getOwnPropertyDescriptor(obj, propName).get;
const fnStr = fn.toString(); // special getter function string
const proxyObj = utils.newProxyInstance(fn, utils.stripProxyFromErrors(handler));

utils.replaceProperty(obj, propName, {get: proxyObj});
utils.patchToString(proxyObj, fnStr);
utils.replaceProperty(obj, propName, {get: proxyObj});
utils.patchToString(proxyObj, fnStr);

return true;
return true;
} else {
return false;
}
};

utils.replaceSetterWithProxy = (obj, propName, handler) => {
const fn = utils.cache.Object.getOwnPropertyDescriptor(obj, propName).set;
const fnStr = fn.toString(); // special setter function string
const proxyObj = utils.newProxyInstance(fn, utils.stripProxyFromErrors(handler));
const desc = utils.cache.Object.getOwnPropertyDescriptor(obj, propName)

utils.replaceProperty(obj, propName, {set: proxyObj});
utils.patchToString(proxyObj, fnStr);
if (desc) {
const fn = utils.cache.Object.getOwnPropertyDescriptor(obj, propName).set;
const fnStr = fn.toString(); // special setter function string
const proxyObj = utils.newProxyInstance(fn, utils.stripProxyFromErrors(handler));

return true;
utils.replaceProperty(obj, propName, {set: proxyObj});
utils.patchToString(proxyObj, fnStr);

return true;
} else {
return false;
}
};

/**
Expand Down Expand Up @@ -1172,5 +1183,36 @@ utils.findRenderingContextIndex = (canvas) => {
return {context: null, contextIndex: -1};
};

utils.osType = (userAgent) => {
// https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform
let result = 'Unknown'
const OSArray = {
'Windows': false,
'macOS': false,
'Linux': false,
'iPhone': false,
'iPod': false,
'iPad': false,
'Android': false,
}

userAgent = userAgent.toLowerCase()

OSArray['Windows'] = userAgent.includes('win32') || userAgent.includes('win64') || userAgent.includes('windows')
OSArray['macOS'] = userAgent.includes('macintosh') || userAgent.includes('mac68k') || userAgent.includes('macppc') || userAgent.includes('macintosh')
OSArray['Linux'] = userAgent.includes('linux')
OSArray['iPhone'] = userAgent.includes('iphone')
OSArray['iPod'] = userAgent.includes('ipod')
OSArray['iPad'] = userAgent.includes('ipad')
OSArray['Android'] = userAgent.includes('android')

for (const i in OSArray) {
if (OSArray[i]) {
result = i
}
}

return result
}

module.exports = utils;
Loading

0 comments on commit 582df95

Please sign in to comment.