Monday, 17 January 2022

Running JavaScript Before Any Other Scripts On A Page

Injecting A Script At The Top Of Your HTML Page


By Strictly-Software

If you are developing an extension for either Firefox, Opera or Chrome, Brave, Edge, and Chromium, then you might come across the need to be able to inject some code into the top of your HTML page so that it runs before any other code.

When developing extensions for Chromium based browsers such as Chrome, Brave and Edge, you will most likely do this from your content.js file which is one of the main files that holds code to be run at certain stages of a pages lifetime.

As the Chrome Knowledge Base says the property values for the "run_at" property include;

  • document_idle, the preferred setting where scripts are guaranteed to run after the DOM is complete and after the window.onload event has loaded all resources which can include other scripts.
  • document_end, content.js scripts are injected immediately after the DOM is complete, but before subresources like images and frames have loaded. So after the DOM is loaded but before window.onload has finished loading external resources.
  • document_start, ensures scripts are injected after any CSS files are loaded but before any other DOM is constructed or any other script is run.  
  • There is of course the "run_at" property in the manifest.json file, which can be set to "document_start", to enable the codes running before other code does. This is especially useful if you need to change header values before a web page loads so that modified values such as the Referer or User-Agent can be modified. However, there may also be a need for you to set up an object or variable that is inserted into the DOM for code within the HTML page to access.

    For example in a User-Agent switcher where you need to both overwrite the Navigator object in JavaScript and the Request header, you may want to create an object or variable that holds the original REAL navigator object or its user-agent so that any page you may create yourself or offer to your users the ability to see the REAL user-agent, browser, language, and other properties if they wanted to.

    For example, I have my own page that I use to show me the current user-agent and list the navigator properties

    However, if they have been modified by my own user-agent switcher extension I also offer up a variable holding the original REAL user-agent so that it can be shown and compared with the spoofed version to see what has changed. I also have a variable that holds the original navigator object in case I want to look at the properties.

    Therefore my HTML page may want to inspect this object if it exists with some code on the page.

    // check to see if I can access the original Navigator object and the user agent string
    if(typeof(origNavigator) !== undefined && origUserAgent !== null)
    {
    	// get the real Browser name with my Detect Browser function using the original Navigator user-agent
    	let realBrowser = Browser.DetectBrowser(origUserAgent);
    
    	// output on the page in a DIV I have
    	G("#RealBrowser").innerHTML = "<b>Real Browser: " + realBrowser "</b>";
    }

    This code just uses a generic Browser detection function for taking a user-agent and finding the Browser name. It even detects Brave by ruling out other browsers and if it is Chrome at the end I check for the Brave properties or mention of the word in the string, which they used to have but newer versions have removed it. 

    However there is hope in the community that they will create a unique user-agent with the word Brave in as at the moment people are having to do object detection which is the better method, and as Brave tries to hide itself, but there are plenty of query strings and other API calls which can be made to find out whether the result indicates Brave rather than Chrome.

    However, at the moment, I am just using a simple detection on a Chrome user-agent that if TRUE indicates that it is actually Brave not Chrome e.g:

    // ensure that a Chrome user-agent is not actually Brave by checking some properties that seem to work to identify the browser at the moment anyway...
    if(navigator.brave !== undefined){
    	braveAgent = (navigator.brave && navigator.brave.isBrave()) ? true : false;				
    }else if(userAgentString.indexOf("Brave") > -1){
    	braveAgent = true;
    }


    However, this article is more about injecting a script into the HEAD of your HTML so that code on the page can access any properties within it.

    As my extension offers an Original Navigator object and a string holding the original/real user-agent before I overwrite it, then I want this code to be the first piece of JavaScript on the page.

    This doesn't have to be limited to extensions and you may have code you want to inject in the HEAD when the DOMLoads before any other code.

    This is a function I wrote that attempts to place a string holding your JavaScript into a new Script block I create on the fly and then insert before any other SCRIPT in the document.head.

    However, if the page is malformed, or has no defined head area it falls back to just appending the script to the document.documentElement object.

    If you pass false in for the 2nd parameter which tells the function whether or not to remove the script after inserting it then if you view the generated source code for the page you will see the injected script code in the DOM.

    The code looks within the HEAD for another script block and if found it inserts it before the first one using insertBefore() however if there is NO script block in the HEAD then the function will just insert the script into the HEAD anyway using the appendChild() method.

    An example of the function in action with a simple bit of JavaScript that stores the original navigator object and user-agent is below. You might find multiple uses for such code in your own work.

    // store the JavaScript in a string
    var code = 'var origNavigator = window.navigator; var origUserAgent = origNavigator.userAgent;";
    
    // now call my function that will append the script in the head before any other and then remove it if required. For testing you may want to not remove it so you can view it in the generated DOM.
    appendScript(code,true);
    
    // function to append a script first in the DOM in the HEAD, with a true/false parameter that determines whether to remove it after sppending it.
    function appendScript(s,r=true){
    
    	// build script element up
    	var script = document.createElement('script');
    	script.type = 'text/javascript';
    	script.textContent = s;
    	
    	// we want our script to run 1st incase the page contains another script e.g we want our code that stores the orig navigator to run before we overwrite it
    
    	// check page has a head as it might be old badly written HTML
    	if(typeof(document.head) !== undefined && document.head !== null)
    	{	
    		// get a reference to the document.head and also to any first script in the head
    		let head = document.head;
    		let scriptone = document.head.getElementsByTagName('script')[0];
    
    		// if a script exists then insert it before 1st one so we dont have code referencing navigator before we can overwrite it		
    		if(typeof(scriptone) !== undefined && scriptone !== null){	
    			// add our script before the first script
    			head.insertBefore(script, scriptone);
    		// if no script exists then we insert it at the end of the head
    		}else{
    			// no script so just append to the HEAD object
    			document.head.appendChild(script);
    		}
    	// no HEAD so fall back to appending the code to the document.documentElement
    	}else{
    		// fallback for old HTML just append at end of document and hope no navigator reference is made before this runs
    		document.documentElement.appendChild(script);
    	}
    	// do we remove the script from the DOM
    	if(r){
    		// if so remove the script from the DOM
    		script.remove();
    	}
    }
    



    I find this function very useful for both writing extensions and also when I need to inject code on the fly and ensure it runs before any other scripts by using a onDOMLoad method.

    Let me know of any uses you find for it.

    Useful Resource: Content Scripts for Chrome Extension Development. 


    By Strictly-Software

    Friday, 7 January 2022

    Make Your First "Hello World" Brave / Chrome / Edge Extension

    Making your 1st Chrome / Brave Extension....

    By Strictly-Software

    This article is about how to go ahead and make your first extension for  Brave, Chrome, or Edge. As I no longer use Chrome but use Brave instead which like Microsoft Edge is based on the core Chromium Open Source standards-compliant browser, any mention of Brave in this article can be applied to Chrome or Edge as well.

    The good thing about choosing to write your first extension for a Chromium-based browser is that once you have done it, it can be applied to 3 major browsers, Chrome, Brave, and Microsoft's replacement for Internet Explorer, Edge. So if you want to maximize your efforts choosing to develop an extension for Chromium gives you much more scope to apply it to other major browsers unlike Mozilla for Firefox. 

    Not only do I like Brave for paying me not any site owner, to watch adverts in cryptocurrency (BAT), it is more secure, with an easy way to allow or prevent tracking cookies, 3rd party cookies, scripts, adverts, popups, and more from following you around the web.

    It does this by stripping out all the tracking codes by default before rendering the page.

    By doing this it also saves bandwidth and therefore time. It also uses TOR as it's an incognito window so you are more secure when trying to avoid people by going through the onion to access many pages that Brave will sometimes automatically redirect you to.

    You can download the Brave Browser from this link and start to strip trackers and earn cryptocurrency for ignoring tiny little adverts that are shown to you in the corner of the screen right now.


    Setting Up Your Extension

    1. Create a folder somewhere on your machine where all the files for the extension will be located. I just created a folder in documents called "Extensions" and then within it for this test a "HelloWorld" sub folder.

    2. Create a manifest.json file with basic info about your extension. The manifest.json file tells Chrome important information about your extension, like its name and which permissions it needs.

    The manifest version should always be 2, because version 1 is unsupported as of January 2014. So far our extension does absolutely nothing, but let’s load it into Chrome / Brave anyway.

    Let's add some info into it which describes the extension.

    {
      "manifest_version": 2,
      "description": "Hello World Extension",
      "name": "Strictly-Software Hello World Extension",
      "version": "0.1.1"
    }

    3. Create a content script which is "a JavaScript file that runs in the context of web pages." This means that a content script can interact with web pages that the browser visits.

    So open a text file and make the script, as we are doing a hello world all we need to do is something simple such as showing an alert box whenever we go to a new URL that shows a message e.g:

    
    // content.js
    alert("Hello from Strictly-Softwares Brave/Chrome extension!");
    

    Save the file in the same folder as all of your other files as content.js

    As we want the alert box to show on every URL we access we need to add a bit of script in the manifest file which tells it to act on <all_urls> you can see this in the below example as we also tell the manifest.json file about our JavaScript that needs to run on all the URLS we access.

    {
      "manifest_version": 2,
      "description": "Hello World Extension",
      "name": "Strictly-Software Hello World Extension",
      "version": "0.1.2022"
      "content_scripts": [
        {
          "matches": [
            "<all_urls>"
          ],
          "js": ["content.js"]
        }
      ]
    }

    If we wanted the extension code to only run on certain pages then we can use regular expression like syntax which you can explore later to define the URLS that our code acts on.

    Also if we were loading multiple JS files into our manifest file, we would use commas within the square brackets to denote them e.g to add jQuery go and get the version of the plugin you want e.g from https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js and save a local copy into your extension folder. 

    There is no point loading it from a remote site each time as it takes time to load, plus they have stopped using the "latest" version in their filename which you used to be able to reference to get the most up to date version from Google's or jQuery's CDN, however they stopped it due to the amount of requests they were getting which was almost on an unintentional DOS scale.

    For framework files you should always get a version that you know works, and save it locally or on a CDN, so that it can be cached and not loaded from a remote site each time. Also there is no need to keep updating it to the next version when one comes out. If it works for the project you are working on then leave the script reference alone. 

    This is something many developers didn't understand by always loading in the latest version remotely, this took network calls, time to load, and it often introduced new bugs into their code. It is far better to store all your code locally so it can be cached and so that you know it works. So to add jQuery into the extension we would do this.

    "js": ["jquery-3.3.1.js", "content.js"]

    The manifest would look like this if you did add extra files in e.g:

    {
      "manifest_version": 2,
      "description": "Hello World Extension",
      "name": "Strictly-Software UserAgent Extension",
      "version": "0.1.2022",
      "content_scripts": [
        {
          "matches": [
            "<all_urls>"
          ],
          "js": ["jquery-3.3.1.js", "lightbox.js", "scripts.js", "content.js"]
        }
      ]
    }

    4. Add a logo for your extension at the size of 24x24 this will appear in your toolbar when you pin it so you can use the extension. At the same time make some more icons that will be used on the brave://extensions/ page when loading up your extension, for example when you click on it to see the details (Name, description, version etc), and elsewhere.

    You can use this page to convert an image, screenshot, logo into the sizes you need > https://icoconvert.com/.

    The icon for the toolbar should be called just icon.png which you can put in the same folder as the other images which you should name with the size on to not get confused. 

    At the same time make .png logos of the sizes 16x16, 48x48 and 128x128. These are put at the top level in the manifest as you can see below as they are used in different places. The toolbar icon is down at the bottom as you can see.

    So the final manifest file will look like this.

    {
      "manifest_version": 2,
      "description": "Hello World Extension",
      "name": "Strictly-Software UserAgent Extension",
      "version": "0.1.2022",
      "icons": {
        "16": "icon16.png",
        "48": "icon48.png",
        "128": "icon128.png"
      },
      "content_scripts": [
        {
          "matches": [
            "<all_urls>"
          ],
          "js": ["content.js"]
        }
      ],
      "browser_action": {
        "default_icon": "icon.png"
      }
    }

    5. Now in Brave/Chrome go to extensions and open it up

    In Brave it will be a URL like brave://extensions/ and Chrome chrome://extensions/. In the top right corner turn developer mode on. Then in the top left corner hit the "Load Unpacked" button and select your folder containing all your files and images.

    You will see your extension appear in the list of already loaded extensions with one of your logos showing e.g:


    5. Clicking on "Details" will show the information from your manifest and a different size logo e.g:


    6. Now select the extension icon in the toolbar to get up your drop down menu of extensions and select the pin so it's pinned to your toolbar e.g:


    7. Now try going to any URL and you should get an alert box pop up straight away with the message you put in the content.js file. Even before other JavaScript loaded content fires from a DOM or Window onload event, this alert should fire straight away e.g:


    8. And there you go, your first Chrome/Brave extension. Obviously, this just a Hello World test showing you how you can create a basic extension and if you are going to make an extension you will need to read up more on all the different features and actions possible.

    However, this is a good guide for someone wondering about how to make an extension or insert code that fires before the page is loaded

    I have an idea for what I need to use this for such as overwriting JavaScript objects and putting my own properties into them so that they load when the page does before any other JavaScript code as well as being accessible to any local code that tries to access them. You can read a bit about this in a later article, injecting a script at the top of your HTML page.

    If you want more information about what you can do just head to the main Chrome extensions page for developers at https://developer.chrome.com/docs/extensions.

    Have fun...

    By Strictly-Software

    Monday, 27 December 2021

    SQL - Using CASE Statements IN SQL Statements

    How To Use IF Statements In Your SET BASED SQL

    By Strictly-Software

    Now if you are new to SQL you may not know the benefits of the CASE statement. It is basically the way you can implement an IF statement within your SET Based SQL.

    I do a lot of work with Horse Racing and I like to rank my horses on a number of variables adding up a "Rating" score by appending values to a default value so that runners with the best score appear at the top.

    An example of this would be the simplified cut down version below where I am adding points to a Ratings column that will be displayed in the final results. I used multiple CASE WHEN THEN ELSE END, statements to check various stats a horse may have and if they meet the criteria I append a score to a rolling count e.g

    This example uses a couple of CASE statements to show me the horses Last Races Official Rating, but also creates a SCORE using a number of factors which I can then order by easily at the end.

    The SQL

    SELECT RacePK,RunnerPK,Racedatetime,IsHandicap,CourseName + N' - ' + RaceTime + ' - ' + HorseName + ' @ ' + CurrentOdds as Info,OfficialRating,
    		CASE WHEN LastRaceFK>0 THEN (SELECT OfficialRating FROM RACE_RUNNERS WITH (NOLOCK)  WHERE RaceFK=run.LastRaceFK AND HorseNameCountry=run.HorseNameCountry) ELSE 0 END as LastRaceOfficialRating,Class		
    		CASE ClassChange WHEN 1 THEN 'UP IN CLASS' WHEN 2 THEN 'DOWN IN CLASS' WHEN 0 THEN 'SAME CLASS' ELSE 'NA' END as ClassChange,
    		CASE	WHEN LastRaceFK = 0 THEN 'NA'
    			WHEN LastRaceFK > 0 AND (SELECT Class FROM RACES WITH (NOLOCK) WHERE RacePK=LastRaceFK) = '' THEN 'NO LAST CLASS INFO' 
    			WHEN LastRaceFK > 0 THEN 'LAST RACE CLASS: ' + (SELECT MyClass + ' - ' + RaceName FROM RACES WITH (NOLOCK) WHERE RacePK=LastRaceFK) ELSE 'NA' END as LastRaceClass, Going, GoingCode,
    		CASE	WHEN LastRaceFK = 0 THEN 'NA'
    			WHEN LastRaceFK > 0 THEN 'LAST RACE GOING: ' + (SELECT UPPER(GOINGCODE) FROM RACES WITH (NOLOCK) WHERE RacePK=LastRaceFK)	
    			WHEN LastRaceFK > 0 AND (SELECT GOINGCODE FROM RACES WITH (NOLOCK) WHERE RacePK=LastRaceFK) = '' THEN 'NO LAST RACE GOING INFO' END as LastRaceGoing,
    		LastFinishPos, FORM,  
    		Score = CASE WHEN Favourite = 1 THEN 50 
    			     WHEN RunnerPK = [dbo].[udf_GET_RUNNER_POSITION](RacePK,2) THEN 35
    			     WHEN RunnerPK = [dbo].[udf_GET_RUNNER_POSITION](RacePK,3) THEN 20 
    			     WHEN RunnerPK = [dbo].[udf_GET_RUNNER_POSITION](RacePK,4) THEN 10 
    			     ELSE 0 END +
    			-- 0 = no change, 1 = up in grade, 2 down in grade, 3 = unknown, -1 default value				
    			CASE WHEN ClassChange = 1 AND KeyWinForm LIKE '%L%' AND (HasMaxOfficialRating = 1 AND Favourite = 1) AND LastFinishPos = 1 THEN 50
    			     WHEN ClassChange = 1 AND KeyWinForm LIKE '%L%' AND (HasMaxOfficialRating = 1 AND Favourite = 1) THEN 45
    		             WHEN ClassChange = 1 AND LastFinishPos = 1 AND (HasMaxOfficialRating = 1 OR Favourite = 1) THEN 40
    		             WHEN ClassChange = 1 AND KeyWinForm LIKE '%L%' THEN 35
    			     WHEN ClassChange = 1 AND KeyWinForm LIKE '%L%' THEN 30			     
    		             WHEN ClassChange = 1 AND KeyForm LIKE '%L%' AND LastFinishPos BETWEEN 2 AND 4 THEN 27						 		
    			     WHEN ClassChange = 1 AND KeyForm LIKE '%L%' THEN 25
    			-- down in grade could have won at this grade before
    			     WHEN ClassChange = 2 AND KeyWinForm LIKE '%L%' AND LastFinishPos = 1 THEN 35 
    			     WHEN ClassChange = 2 AND KeyWinForm LIKE '%L%' AND LastFinishPos BETWEEN 2 AND 4 THEN 30
    			     WHEN ClassChange = 2 AND KeyWinForm LIKE '%L%' THEN 27
    			     WHEN ClassChange IN(0,1) THEN 5
    			     WHEN ClassChange = 2 THEN 3
    			     WHEN ClassChange IN(3,-1) THEN - 5
    			     ELSE 0
    			     END + 
    			-- new IF for no of runs the more win percentage the better 
    			CASE WHEN Runs > 5 AND WinPerc = 0 THEN -20   
    			     WHEN Runs > 5 AND WinPerc = 100 THEN 100
    			     WHEN Runs > 2 AND WinPerc = 100 THEN 50
    			     WHEN Runs > 5 AND PlacePerc = 100 THEN 60
    			     WHEN Runs > 2 AND PlacePerc = 100 THEN 30
    			     WHEN Runs > 5 AND PlacePerc > 70 THEN 50
    			     WHEN Runs > 2 AND PlacePerc > 70 THEN 30
    			     WHEN Runs > 2 AND LosePerc = 100 THEN -50
    			     WHEN Runs > 5 AND LosePerc > 60 THEN -60
    			     WHEN Runs = 0 OR LOSEPERC > 70 THEN -50 ELSE -10 END +
    			 -- Official Rating higher the better
    			CASE WHEN OfficialRating > 170 THEN 300
    			     WHEN OfficialRating > 160 THEN 275
    			     WHEN OfficialRating > 150 THEN 250
    			     WHEN OfficialRating > 125 THEN 200
    			     WHEN OfficialRating > 110 THEN 175
    			     WHEN OfficialRating > 105 THEN 150
    			     WHEN OfficialRating > 105 AND IsHandicap = 1 THEN 100
    			     WHEN HasMaxOfficialRating = 1 THEN 50
    			     ELSE 10 END
    FROM	RACES as ra  with (nolock)
    JOIN	RACE_RUNNERS as run with (nolock)  
    	ON	ra.RacePK = run.RaceFK 
    JOIN	COURSES as c  with (nolock) 
    	ON	c.CoursePK = r.CourseFK
    WHERE	RacePK = 269330 -- current race I am looking at


    The Results

    Below are the results from that query outputted in MS SQL Management Studio.




    Another Example


    This is where I am using a CASE WHEN THEN ELSE END, statement in the ORDER By clause to show the output of a race card. 

    The race could be finished and in that case I would want the ORDER of the results to be from no 1 (winner) to the horse that finished last. I would also want any runners not finishing who would get a  finish position of 0 appearing last. 

    I would also want any non-runners, horses who were pulled out of the event, before the race to appear at the bottom of the results.

    Also with racing, in the flat, horses start the race in stalls, so if it is a flat race I want to show the stall they are in, if the race is a jump or NHF (Bumper or National Hunt Flat Race), then they use no stalls so I would not order by stall no.

    The SQL

    SELECT	RunnerPK,Racename,raceType,HorseName,Jockey,NonRunner,FinalOdds,CurrentOdds,Draw,Finishposition,favourite,officialrating
    FROM	RACE_RUNNERS as run  WITH (nolock)
    JOIN	RACES as ra  WITH (nolock)
    	ON ra.RacePK=run.RaceFK
    WHERE	RacePK=270423
    ORDER BY CASE WHEN nonrunner=1 THEN 150
    	      WHEN EXISTS(select top(1) runnerPK from race_runners as r1 WITH (nolock) where r1.Racefk=ra.RacePK and finishposition>0) THEN
    		   CASE WHEN finishposition=0 then 100 ELSE finishposition END 
    	      ELSE CASE when ra.racetype IN('NH','B') THEN horsename else draw END
    	 END 

    The Results

    Below are the results from that query outputted in MS SQL Management Studio.




    As I hope you can see the use of a CASE statement either in a SELECT clause or an ORDER BY is very useful for adding an IF statement into a SET based query. 

    You can also use them in your JOINS to help decide which table you actually JOIN onto, for example if I had two tables, one for RACES that had not been run yet, and one for RACES that had finished I could add a CASE statement into the JOIN so that if there existed a runner with a finish position or a RACE with a finishing time I would join to the RACE_RESULTS table and for RACES not run yet I would join to the RACE_CARD table (if they were named like that for races before running and after a result was in).

    There are actually lots of ways you can use CASE statements in your SQL and it may help you to be able to CONVERT looping code or procedural code with actual IF statements in a ROW by ROW CURSOR or LOOP into a SET BASED SQL statement that will perform a lot quicker.

    Please post your favourite CASE statement usages in the comments section.


    By Strictly-Software

    Tuesday, 7 December 2021

    Test Your Anti Virus Software

    A Quick Way To Test If Your Computers Anti-Virus Software Is Working

    By Strictly-Software

    This is a quick and quite a simple way of testing if your PC is protected properly from files that may contain viruses or malware. It has apparently been around for a long time but I only stumbled across it tonight and when I tested it against my AV tools I was surprised at the results.

    The test is called a Eicar test file is a file, developed by the EICAR organization, that is used in testing anti-virus scanners for their integrity in detecting viruses. The actual file is simply a text file of either 68 or 70 bytes that can be created using any text editing program like Notepad. It is not actually a virus but the characters within the file should flag a hit in most Anti Virus tools making them think it is one.

    With so many free anti-malware / virus software out there to use it can be a case that you have multiple apps installed to protect your computer as I have found that some AV products will detect some malware, and others malware that the previous products didn't find.

    Therefore I have found that having more than one AV / Anti Malware product on my computer is the best policy just in case something is found by old school virus definitions or by heuristic behaviour detection which other AV products use.

    I read something the other day about Bitcoin miners hacking into a quantum computer at some US university to leverage it's super power to mine coins. Obviously their standard AV software didn't detect whatever program was running so they actually came up with a new solution which I really don't understand why home PC users couldn't use as well.

    It's a pretty simple concept in that the Quantum Computer just like any computer should only be running certain "allowed" programs.  System programs that operate the machine and then programs that have been installed on the machine by admin. All the new anti virus tool did was hold a list of every program allowed to run on the machine, and then it would constantly scan the Task Manager or equivalent tool and if it found any program executing that wasn't on the "allowed" list it would terminate the process and quarantine or remove the executable.

    To me this sounds like quite a simple solution to malware detection and a lot better than constantly updating AV software with definition lists. How hard would it be to create a program that logged all tasks and services that were OS based, and then add to this whitelist any programs that were properly installed by an administrator. You could run the setup of this program in safe mode, or on a clean install so that it stored only safe OS programs in it's whitelist and then when a new program was installed it would be added to the same list.

    Then the AV tool would just run alongside your Task Manager looking for any process not in it's white list and flag it when found. The user could then inspect the properties and location of the file and decide whether it was legitimate or illegal and either add it to the white list or have it removed. I might even have a crack at making something like this.

    Anyway this is about testing your current system to see if your AV software will detect the following file as malware which it should. I don't know what this does if anything, or whether it just matches a virus definition from some time back but I ran the test earlier and you can see my results below.

    Run Your Own Anti Virus Test

    1. Open Notepad -> Run -> Notepad

    2. Type the following text into the file: 
    X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

    3. Save the file somewhere on your PC as an executable, e.g I saved my file in Documents as AVTest.exe

    4. If you have multiple AV tools in your context menu. You can right click above the file and test each one to see if they detect the file as malware e.g


    5. However if you are on Windows and haven't replaced Windows Defender with a premium AV tool it should always be running and detect threats as they come. It does on my PC despite me having other AV tools. As soon as I save the AVtest.exe file on my machine Windows Defender pops up a message saying it has detected malware on my machine in the top right corner and in the bottom right corner another message tells me that I don't need to do anything as "Detected threats are being cleaned" and within a minute the file disappears from my Documents folder. Therefore if you want to test other AV software you need to have them up and running and ready so you can do a quick single file virus test from your context menu before Windows Defender removes it.



    Notice the two Windows Defender messages in the right hand corners of the screen when I save the file.

    So I have a variety of AV tools on my system but keep Windows Defender running at all times. These were the results I got from my Context Menu test. Please let me know of any other free AV tools that either detect or DON'T detect this as a virus.

    -Windows Defender: It detected the file as a virus as soon as I saved it. Showed me warning messages and said it would be removing it. Within a minute or so the file had gone.
    -Malwarebytes Anti-Malware: Running a scan on this file from the context menu it detected it and quarantined it for me but a full scan did not find it.
    -McAfee PRO used  instead of Windows Defender as my main virus checker - DID NOT DETECT IT AS A VIRUS
    -Emsisoft Security Center - DID NOT DETECT IT AS A VIRUS.
    -SuperAntiSpyware (Free Edition) - DID NOT DETECT IT AS A VIRUS

    Now I cannot be a 100% sure that the reason that the last two apps did NOT detect it as a virus was because Windows Defender had somehow put a lock on the file so that they could not detect it or something however the free version of Malware Anti-Malware did detect it when running a single file scan from the right click context menu.

    Anyway this is a good test just to make sure your computer is detecting virus files and it only takes a few minutes to copy that string of letters and place them in a text file, save it, and see which AV tool shoots up a message that a virus has been detected.

    It's an old trick so I don't claim to be the first to know about it but I was just surprised at the results and it is always good to know your machine is protected and this is a very simple way without installing an actual virus.

    Let me know of any other FREE AV / Anti Malware tools that don't detect it as malware in the comments.

    By Strictly-Software

    Thursday, 28 October 2021

    Need Help Editing Your Blogger Blog?

    Do You Need Help Editing Your Blogger Site

    By Strictly-Software

    After my last post about editing blogger blogs using JavaScript on the client side due to the lack of functionality in the back end of the admin side of blogger I was contacted by a couple of people who needed help on their blogs.

    I have implemented features such as the following using the JavaScript/Text widgets that you can add to your layout for adding CSS Styles and JavaScript code to do the following so far:

    1. Added the code I use to turn my SEO optimisation on or off. In my sidebar there is a section where you can turn bolded sentences or words off and on again. Some people like having the bold on as it holds the key information in a blog piece and helps with skim reading. However as it is loaded server side to aid SEO, I can turn it off with client side JavaScript either on each page or by using cookies to remember your choice when doing so that when you come back the next time it will have remembered your choice.

    2. Used JavaScript to totally change a blogs colour scheme from a default light grey to a dark blue and white scheme. Similar to using the JavaScript widgets but with a bit more code and use of the querySelector and querySelectorAll methods and then looping through matching elements to change their colours using .style.backgroundColor & .style.color methods.

    3. Again changed the layout of the blog by expanding buttons that were too small on search bars, adding in custom search engines that only search certain sites, usually related blogs or sites about the same content that the blog in question was about.

    4. Ensured Google Adsense was enabled and turned on in the best way to increase revenue streams from visitors to the site.

    5. For a blog that was hotlinking to a site that had no SSL anymore to display images. I obtained the original image and uploaded into Blogger so that it was stored IN the blog and referenced from there. People are often put off sites with no HTTPS URL such as my own, purely due to Browser warning pages that believe every site nowadays needs to have an SSL.

    Well if you are not actually buying anything or logging into the site or passing personal information to it e.g it's just a blog or site with text and pictures you are reading then there is really no danger at all from going to the uncertified site. 

    Just click Advanced and then "Go To Site Anyway" or the comparable message. You can check this out by going to my own site www.strictly-software.com, however I have found the if you use BRAVE as your browser it or either one of the following extensions remembers that you have gone there and prevents the same MalwareBytes Browser Guardwarning page from showing: or DuckDuckGo Privacy Essentials.

    You can check 2 of these sites out here:



    And check out the changes and features for yourself.

    If you are interested in getting some widgets added to your own Blogger site then contact me by email and we can work out a price for the work. There is a lot we can do client side with JavaScript to replace the lack of functionality the old Blogger system had for changing layout and colours etc on the page loading.


    By Strictly-Software

    Thursday, 21 October 2021

    Changing Blogger With JavaScript

    Using JavaScript To Edit Blogger Layout

    By Strictly-Software

    If you are using Googles blogger to output content then there will often be times where you want to edit the layout depending on the page you are on, or the content that is shown.

    I recently had a site where I needed to edit the content in multiple places depending on whether a GoFundMe post was being shown on the homepage, or it's own page. As I also had a mini GoFundMe logo in the sidebar I didn't want both images to be shown at the same time.

    I also had a Custom Google Search Bar which only searched a certain number of websites related to the content on the blog.

    Therefore the logic I needed was to.

    1. Once the page had loaded I needed to ensure if a post of GoFundMe was shown on the page then I needed to remove the sidebar image in ID #Image4.
    2. Just doing a test for #Image4 doesn't work as the widgets change names server side before output therefore I need to list out the pages / URLS that the post appears on where I know that the image in the side bar and the main post image both exist.
    3. I need to add text to a special Google Search Bar when the site has loaded, sometimes this can be slow depending on Google's Servers, so therefore I decided to put it in a window.onload event to ensure all other images and external items had loaded before I edited the input bar.
    4. On focus of the search bar I need to clear it to allow people to put their own search terms.
    5. On leaving the search bar if it's empty then I need to put the default text back in, a simple onblur, onfocus toggle.

    As the widget I added (an HTML/JavaScript widget), was at the bottom of the page the likelihood of the code running after these items had loaded was high so the chances of the code running before the search bar being loaded was low. 

    However on the chance it did run, the window.onload event unlike DOMLoad events ensure that all external items have loaded. If I tried a DOMLoad event there was a small chance that the code would run before the items it was affecting had loaded.

    Therefore to test that the page was showing a post with the GoFundMe on it and therefore removing a server side loaded item from the page I used Regular Expressions

    I looked at all the places the pages loaded this post and they were the homepage, the homepage for mobile or non mobile sites, with or without the Google # link for the search bar tab being in the URL, plus certain labels that only this post appeared on.

    The Regular Expression I came up with that worked using my test page I made in HTML & JS that worked was this.
    ^https:\/\/sitename.blogspot.com\/?(\??(m=\d)?(#gsc.tab=\d+)?|\S+?GoFundMe\S+?|\S+?\/(?:Donate|Donations|GoFundMe)\S+?)?$

    This expression uses the document.location.href value to run on and is anchored from the start to end of input with ^ and $.

    It always contains the main domain in the URL and I have made the ending / optional with a ? e.g escaped with a forward slash first and putting a question mark after it e.g \/?.

    The next part is whether or not a querystring ? exists which is why there is an escaped question mark first to denote a real question mark, followed by another one to say it "May or may not be there". 

    The next part is a check to see if there has been a toggle used on the site to change from a mobile view to a website view. They use a simple querystring value for this m=0 (website), m=1 (mobile), so I have (m=\d) which denotes m=(any digit), just incase they change or append digits.

    This is the 1st part of an OR section wrapped in a group. I could have put ?: at the start of the group to say "do not store", but as I am not back referencing or using the group in replacements then I didn't bother.

    The whole OR is broken down into this logic.

    The logic contained within the OR (expression|expression|expression) is the equivalent to this long explanation:

    (\??[optional back slash](m=\d)?[optional mobile/website URL toggle to any digit](#gsc.tab=\d+)[optional anchor that denotes Google has loaded up its search bar code as if you are quick you can catch a document.location.href value without this on it]. Then a wrap around the main post called GoFundMe with \S+? which makes it look for non space characters 1 or more times before or after the words GoFundMe which appear on the posts page in the middle of the URL e.g https://sitename.blogspot.com/2021/10/httpssitename.blogspot.comGoFundMe.html.html?m=0#gsc.tab=0 and then finally a look for the 3 labels that are used to find the page and appear in the URL like so https://sitename.blogspot.com/search/label/Donations?m=0 (as you can see when I copied the URL the page hadn't loaded in the Google Search Bar which is why there is no #gsc.tab=0 in the URL) so this is why I have made that part optional as well.)

    So that regular expression handles the following URL's whether or not the Google code has loaded or there is code to force it show a mobile site or website version of the blog.

    https://sitename.blogspot.com
    https://sitename.blogspot.com/
    https://sitename.blogspot.com/?
    https://sitename.blogspot.com/?m=0 or https://sitename.blogspot.com/?m=1 
    https://sitename.blogspot.com/#gsc.tab=0
    https://sitename.blogspot.com/?m=1#gsc.tab=0
    https://sitename.blogspot.com/2021/10/httpssitename.blogspot.comGoFundMe.html.html#gsc.tab=0

    I made a quick function call to querySelector so that it is short, I always used G when it was document.getElementById(val), so I used it again as to me it means GET G(x) = GetMe(x) a reference to the small framework I made which is on the blog somewhere e.g

    G = function(v){return document.querySelector(v)};

    Then I can reference objects by class, selector or ID easily with a one letter function e.g

    var el=G(".gsc-search-button > input");
    G("#Image4").remove();

    The final code I inserted into the JavaScript/HTML widget was this.
    
    <script type="text/javascript">
    G = function(v){return document.querySelector(v)};
    window.addEventListener("load", function() 
    {
    	if(G("#gsc-i-id1")){
    		G("#gsc-i-id1").value = "Search for similar articles here";
    	}
    	G("#gsc-i-id1").addEventListener("focus",function(){
    		G("#gsc-i-id1").value="";
    	});
    	G("#gsc-i-id1").addEventListener("blur",function(){
    		if(G("#gsc-i-id1").value==""){
    			G("#gsc-i-id1").value = "Search for similar articles here";
    		}
    	});	
    });
    // As these elements are loaded server side they will exist when any JavaScript gets to run so no need to put inside the Window.Onload event
    var exp = new RegExp(/^https:\/\/sitename.blogspot.com\/?(\??(m=\d+)?(#gsc.tab=\d+)?|\S+?GoFundMe\S+?|\S+?\/(?:Donate|Donations|GoFundMe)\S+?)?$/,"gi");
    if(exp.test(document.location.href)){
    	G("#Image4").remove();
    }
    // search button never appears wide enough to say "Search" so expand
    var el=G(".gsc-search-button > input"); // Use selector to get child input of class
    gsc-search-button which is used numerous times
    if(el){el.style.width="60px";} // just a safety test to ensure it's there - which it should be
    </script>
    

    It works and I am happy to see no double GoFundMe images on the page and the focus/blur code working fine.

    It is just an example of using JavaScript to modify the DOM when you cannot use Server Side code to initially output it.

    © 2021 By Strictly-Software

    Friday, 6 August 2021

    Fix for Wifi Adapter not working - no WiFi

    A WiFi Fix Without Rebooting PC

    By Strictly Software

    I just woke up again on my laptop at 5am, and the keyboard had all changed, I noticed as I went onto YouTube to post a video onto Twitter about the US Government wanting to spy on everyone's text messages and stop any that contain mis-information. 

    Now if the US does it then you can be sure the UK GOV will follow as we are already halfway down that slippery wedge towards dystopia. The UK is already becoming a police state using COVID as the cover to implement draconian laws as everyone is worrying about this or that variant and whether or not to get a vaccine just to get a passport that will control your social life, and allow total monitoring of your activities by the Government. 

    You can watch the video below about the invasion of US citizens privacy here. What happens in the US usually comes to the UK soon after but when it comes to mass surveillance the NSA like to use GCHQ to test their Prism algorithms and mass home population surveillance techniques out on 1st before using it back home. 

    Why? Well because we don't have a real written down constitution or Bill of Rights that protect citizen freedoms is the main reason. The 2nd is our constant desire to be bed buddies with the US, in our "Special Relationship", and keep them sweet by being useful to them, hoping for a share in their data gathering techniques.


    I noticed the keyboard change when I went to put a hash tag in and got a | pipe instead and the " quotes were an @ sign. So I did the quick fix I outlined from the other night > "Quick Fix To Keyboard Layout Change"

    However I was trying to tweet this out from YouTube to Twitter. Twitters site was up, and I kept pressing "Tweet" but it kept responding with a "There is a problem, try again" message after 20 seconds of non activity.

    It was obviously using AJAX as the page didn't refresh, but a quick ping to Twitter.com came back with no server response. It was then I noticed that somehow my WiFi had gone, saying my connection to my router was weak.

    Sites that use AJAX for everything, especially posting, should really be able to tell if you are online or not as the reason for a post not appearing

    Rather than freaking out someone as the site is still on the screen, and most of the API is in JavaScript so you can still hit buttons and get the impression you are online. There must be a load of ways that after 3 failed post attempts or even 1, that an AJAX API could tell you that you were no longer online in a message.

    A method that when you press the button sees if you can remotely access a site that is always up, for instance, would be easy. Then the error message could notify you that you are offline. If they just did a FORM submission when posting Tweets instead of using AJAX you would instantly know anyway from the "No Internet Access" page your web browser would bring up.

    So once I had found out that I could not PING Twitter, I checked my Wi-Fi status and it said I had a weak connection to my router. 

    Now before I did the keyboard fix, I was online and everything was okay, so I don't know if somehow that quick hot key fix could somehow cause your Wi-Fi adapter to fail, but the two actions seem causally linked. 

    So I went to the built in Windows "Troubleshoot Problems" wizard you get when you click on your WiFi symbol in your Desk Tray to run a diagnostic test that clears the DNS, resets your router and adapter and then tries to ping an outside site to see if you have Internet connectivity restored again or a problem accessing the Internet.



    I was getting back 3 error messages saying I was offline, my RealTek Wi-Fi adapter was not working, and a default Wi-Fi adapter message, The wizards cure for the problem was to use Ethernet cables but I am not linking loads of cables together just to get round this simple problem.

    Usually at first I just try to turn Flight Mode on/off and see if that changes the number of Wi-Fi routers that appear in my list

    If it doesn't and I turn Wi-Fi on/off and that still doesn't show my router then one way to fix it is to just log out and log back in again - or reboot if you want to.

    However a quicker fix I have found to this commonly occurring RealTek (HP) laptop Wi-Fi adapter problem is to first go to the Device Manager app, under the Windows key, bottom left corner.



    I then just go to the Network Adapters section and a load will pop up, if the RealTek Wireless LAN is out of action, usually a red cross will appear next to it. 

    In this screenshot I had already fixed it so I wasn't going to try and break it again on purpose just to get a real screenshot. However a red cross next to the adapter having problems is usually the sign you need to double click that adapter and open the menu for it.


    I usually try both the "Update Driver Software" and "Scan for hardware changes" options to see which one fixes it but usually one does. It is a lot easier than having to save all your work, remember which files were open, and reboot your laptop.

    After fixing the adapter in Device Manager I always run another diagnostic test to ensure there is no other problems but usually my Wi-Fi is instantly restored as the router comes back online and the adapter connects to it.

    I always finish off with a quick ping to the site I was on to ensure even though I am online they are too but you can easily skip this step.


    And hey ho, I am back online, not banned from Twitter which was on of my 1st thoughts when they couldn't post a Tweet and give me an "offline" status error message. 

    However that is the problem with sites that are full of API Jizz, they use it so much they cannot even show you the simplest message at times when all you need to know is that you are offline.

    I hope the fix for the keyboard change is not related to the Wi-Fi adapter change but it could be somehow, it's just odd how I was online with a wrong keyboard layout, then I did the quick fix to reset it and then became offline. 

    If anyone knows any reason the two might be connected please let me know.

    Thanks.....

    By Strictly Software

    © 2021 Strictly Software