Advertisement
Guest User

Untitled

a guest
Nov 20th, 2019
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.88 KB | None | 0 0
  1. const newProto = navigator.__proto__
  2. delete newProto.webdriver
  3. // eslint-disable-next-line
  4. navigator.__proto__ = newProto
  5.  
  6.  
  7. window.navigator.chrome = {
  8. runtime: {},
  9. // etc.
  10. };
  11.  
  12. window.console.debug = () => {
  13. return null
  14. }
  15.  
  16.  
  17.  
  18. const originalQuery = window.navigator.permissions.query
  19. // eslint-disable-next-line
  20. window.navigator.permissions.__proto__.query = parameters =>
  21. parameters.name === 'notifications'
  22. ? Promise.resolve({ state: Notification.permission }) //eslint-disable-line
  23. : originalQuery(parameters)
  24.  
  25. // Inspired by: https://github.com/ikarienator/phantomjs_hide_and_seek/blob/master/5.spoofFunctionBind.js
  26. const oldCall = Function.prototype.call
  27. function call () {
  28. return oldCall.apply(this, arguments)
  29. }
  30. // eslint-disable-next-line
  31. Function.prototype.call = call
  32.  
  33. const nativeToStringFunctionString = Error.toString().replace(
  34. /Error/g,
  35. 'toString'
  36. )
  37. const oldToString = Function.prototype.toString
  38.  
  39. function functionToString () {
  40. if (this === window.navigator.permissions.query) {
  41. return 'function query() { [native code] }'
  42. }
  43. if (this === functionToString) {
  44. return nativeToStringFunctionString
  45. }
  46. return oldCall.call(oldToString, this)
  47. }
  48.  
  49. // eslint-disable-next-line
  50. Function.prototype.toString = functionToString
  51.  
  52.  
  53.  
  54. Object.defineProperty(navigator, 'languages', {
  55. get: () => ['en-US', 'en'],
  56. });
  57.  
  58.  
  59. function mockPluginsAndMimeTypes () {
  60. /* global MimeType MimeTypeArray PluginArray */
  61.  
  62. // Disguise custom functions as being native
  63. const makeFnsNative = (fns = []) => {
  64. const oldCall = Function.prototype.call
  65. function call () {
  66. return oldCall.apply(this, arguments)
  67. }
  68. // eslint-disable-next-line
  69. Function.prototype.call = call
  70.  
  71. const nativeToStringFunctionString = Error.toString().replace(
  72. /Error/g,
  73. 'toString'
  74. )
  75. const oldToString = Function.prototype.toString
  76.  
  77. function functionToString () {
  78. for (const fn of fns) {
  79. if (this === fn.ref) {
  80. return `function ${fn.name}() { [native code] }`
  81. }
  82. }
  83.  
  84. if (this === functionToString) {
  85. return nativeToStringFunctionString
  86. }
  87. return oldCall.call(oldToString, this)
  88. }
  89. // eslint-disable-next-line
  90. Function.prototype.toString = functionToString
  91. }
  92.  
  93. const mockedFns = []
  94.  
  95. const fakeData = {
  96. mimeTypes: [
  97. {
  98. type: 'application/pdf',
  99. suffixes: 'pdf',
  100. description: '',
  101. __pluginName: 'Chrome PDF Viewer'
  102. },
  103. {
  104. type: 'application/x-google-chrome-pdf',
  105. suffixes: 'pdf',
  106. description: 'Portable Document Format',
  107. __pluginName: 'Chrome PDF Plugin'
  108. },
  109. {
  110. type: 'application/x-nacl',
  111. suffixes: '',
  112. description: 'Native Client Executable',
  113. enabledPlugin: Plugin,
  114. __pluginName: 'Native Client'
  115. },
  116. {
  117. type: 'application/x-pnacl',
  118. suffixes: '',
  119. description: 'Portable Native Client Executable',
  120. __pluginName: 'Native Client'
  121. }
  122. ],
  123. plugins: [
  124. {
  125. name: 'Chrome PDF Plugin',
  126. filename: 'internal-pdf-viewer',
  127. description: 'Portable Document Format'
  128. },
  129. {
  130. name: 'Chrome PDF Viewer',
  131. filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai',
  132. description: ''
  133. },
  134. {
  135. name: 'Native Client',
  136. filename: 'internal-nacl-plugin',
  137. description: ''
  138. }
  139. ],
  140. fns: {
  141. namedItem: instanceName => {
  142. // Returns the Plugin/MimeType with the specified name.
  143. const fn = function (name) {
  144. if (!arguments.length) {
  145. throw new TypeError(
  146. `Failed to execute 'namedItem' on '${instanceName}': 1 argument required, but only 0 present.`
  147. )
  148. }
  149. return this[name] || null
  150. }
  151. mockedFns.push({ ref: fn, name: 'namedItem' })
  152. return fn
  153. },
  154. item: instanceName => {
  155. // Returns the Plugin/MimeType at the specified index into the array.
  156. const fn = function (index) {
  157. if (!arguments.length) {
  158. throw new TypeError(
  159. `Failed to execute 'namedItem' on '${instanceName}': 1 argument required, but only 0 present.`
  160. )
  161. }
  162. return this[index] || null
  163. }
  164. mockedFns.push({ ref: fn, name: 'item' })
  165. return fn
  166. },
  167. refresh: instanceName => {
  168. // Refreshes all plugins on the current page, optionally reloading documents.
  169. const fn = function () {
  170. return undefined
  171. }
  172. mockedFns.push({ ref: fn, name: 'refresh' })
  173. return fn
  174. }
  175. }
  176. }
  177. // Poor mans _.pluck
  178. const getSubset = (keys, obj) =>
  179. keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {})
  180.  
  181. function generateMimeTypeArray () {
  182. const arr = fakeData.mimeTypes
  183. .map(obj => getSubset(['type', 'suffixes', 'description'], obj))
  184. .map(obj => Object.setPrototypeOf(obj, MimeType.prototype))
  185. arr.forEach(obj => {
  186. arr[obj.type] = obj
  187. })
  188.  
  189. // Mock functions
  190. arr.namedItem = fakeData.fns.namedItem('MimeTypeArray')
  191. arr.item = fakeData.fns.item('MimeTypeArray')
  192.  
  193. return Object.setPrototypeOf(arr, MimeTypeArray.prototype)
  194. }
  195.  
  196. const mimeTypeArray = generateMimeTypeArray()
  197. Object.defineProperty(navigator, 'mimeTypes', {
  198. get: () => mimeTypeArray
  199. })
  200.  
  201. function generatePluginArray () {
  202. const arr = fakeData.plugins
  203. .map(obj => getSubset(['name', 'filename', 'description'], obj))
  204. .map(obj => {
  205. const mimes = fakeData.mimeTypes.filter(
  206. m => m.__pluginName === obj.name
  207. )
  208. // Add mimetypes
  209. mimes.forEach((mime, index) => {
  210. navigator.mimeTypes[mime.type].enabledPlugin = obj
  211. obj[mime.type] = navigator.mimeTypes[mime.type]
  212. obj[index] = navigator.mimeTypes[mime.type]
  213. })
  214. obj.length = mimes.length
  215. return obj
  216. })
  217. .map(obj => {
  218. // Mock functions
  219. obj.namedItem = fakeData.fns.namedItem('Plugin')
  220. obj.item = fakeData.fns.item('Plugin')
  221. return obj
  222. })
  223. .map(obj => Object.setPrototypeOf(obj, Plugin.prototype))
  224. arr.forEach(obj => {
  225. arr[obj.name] = obj
  226. })
  227.  
  228. // Mock functions
  229. arr.namedItem = fakeData.fns.namedItem('PluginArray')
  230. arr.item = fakeData.fns.item('PluginArray')
  231. arr.refresh = fakeData.fns.refresh('PluginArray')
  232.  
  233. return Object.setPrototypeOf(arr, PluginArray.prototype)
  234. }
  235.  
  236. const pluginArray = generatePluginArray()
  237. Object.defineProperty(navigator, 'plugins', {
  238. get: () => pluginArray
  239. })
  240.  
  241. // Make mockedFns toString() representation resemble a native function
  242. makeFnsNative(mockedFns)
  243. }
  244. try {
  245. const isPluginArray = navigator.plugins instanceof PluginArray
  246. const hasPlugins = isPluginArray && navigator.plugins.length > 0
  247. if (isPluginArray && hasPlugins) {
  248. return // nothing to do here
  249. }
  250. mockPluginsAndMimeTypes()
  251. } catch (err) {}
  252.  
  253. try {
  254. /* global WebGLRenderingContext */
  255. const getParameter = WebGLRenderingContext.getParameter
  256. WebGLRenderingContext.prototype.getParameter = function (parameter) {
  257. // UNMASKED_VENDOR_WEBGL
  258. if (parameter === 37445) {
  259. return 'Intel Inc.'
  260. }
  261. // UNMASKED_RENDERER_WEBGL
  262. if (parameter === 37446) {
  263. return 'Intel Iris OpenGL Engine'
  264. }
  265. return getParameter(parameter)
  266. }
  267. } catch (err) {}
  268.  
  269. try {
  270. if (window.outerWidth && window.outerHeight) {
  271. return // nothing to do here
  272. }
  273. const windowFrame = 85 // probably OS and WM dependent
  274. window.outerWidth = window.innerWidth
  275. window.outerHeight = window.innerHeight + windowFrame
  276. } catch (err) {}
  277.  
  278. Object.defineProperty(HTMLIFrameElement.prototype, 'contentWindow', {
  279. get: function() {
  280. return window;
  281. }
  282. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement