Friday, October 30, 2020

C# .NET Validate Drive Letter with compiler optimization aggressive in-lining for large fall-through case statements

Here's a surprise,  range operator is beaten by a large set of serial cases statements! 




In the below code example which validates a drive letter,  by 

using System.Runtime.CompilerServices;

you can adorn the case-statement method to be compiled with  

[MethodImplAttribute(MethodImplOptions.AggressiveOptimization )] and/or

[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]

to surprising results.  I was surprised by v6. v5 and v6 win on alternative runs.

Full documentation here - https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.methodimploptions


Source Code

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
					
public static class Program
{
	 //Fri 30-Oct-20 2:17pm metadataconsulting.ca 
	 //https://metadataconsulting.blogspot.com/2020/10/C-NET-Validate-Drive-Letter-with-compiler-optimization-aggressive-in-lining-for-large-fall-through-case-statements.html
	 //-> this method does not exist on the interwebs, trivial?
	 //-> fun with compiler switches to optimize case statements 
	
	 public static bool isValidDriveLetter(this string drivewithcolon)
	 {
		 
		 if (drivewithcolon.Length == 2 && drivewithcolon[1] == ':')
		 {
			 drivewithcolon = drivewithcolon.ToUpper();
			 // this is surprisingly faster than the equivalent if statement
			 switch (drivewithcolon[0])
			 {
				 case 'A':
				 case 'B':
				 case 'C':
				 case 'D':
				 case 'E':
				 case 'F':
				 case 'G':
				 case 'H':
				 case 'I':
				 case 'J':
				 case 'K':
				 case 'L':
				 case 'M':
				 case 'N':
				 case 'O':
				 case 'P':
				 case 'Q':
				 case 'R':
				 case 'S':
				 case 'T':
				 case 'U':
				 case 'V':
				 case 'W':
				 case 'X':
				 case 'Y':
				 case 'Z':
					 return true;
				 default:
					 return false;
			 }
		 }
		 else
			 return false; 

	 }
     //range operator	
	 public static bool isValidDriveLetterV2(this string drivewithcolon)
	 {
		 		 
		 if (drivewithcolon.Length == 2 && drivewithcolon[1] == ':')
		 {
			 drivewithcolon = drivewithcolon.ToUpper();
			 if (drivewithcolon[0] >= 'A' && drivewithcolon[0] <= 'Z') 
			 	return true;
			 else 
				 return false; 
		 }
		 else
			 return false; 

	 }
	
	 [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
	 public static bool isValidDriveLetterV3(this string drivewithcolon)
	 {
		 
		 if (drivewithcolon.Length == 2 && drivewithcolon[1] == ':')
		 {
			 drivewithcolon = drivewithcolon.ToUpper();
			 // this is surprisingly faster than the equivalent if statement
			 switch (drivewithcolon[0])
			 {
				 case 'A':
				 case 'B':
				 case 'C':
				 case 'D':
				 case 'E':
				 case 'F':
				 case 'G':
				 case 'H':
				 case 'I':
				 case 'J':
				 case 'K':
				 case 'L':
				 case 'M':
				 case 'N':
				 case 'O':
				 case 'P':
				 case 'Q':
				 case 'R':
				 case 'S':
				 case 'T':
				 case 'U':
				 case 'V':
				 case 'W':
				 case 'X':
				 case 'Y':
				 case 'Z':
					 return true;
				 default:
					 return false;
			 }
		 }
		 else
			 return false; 

	 }	
	
	 [MethodImplAttribute(MethodImplOptions.AggressiveOptimization)]
	 public static bool isValidDriveLetterV4(this string drivewithcolon)
	 {
		 
		 if (drivewithcolon.Length == 2 && drivewithcolon[1] == ':')
		 {
			 drivewithcolon = drivewithcolon.ToUpper();
			 // this is surprisingly faster than the equivalent if statement
			 switch (drivewithcolon[0])
			 {
				 case 'A':
				 case 'B':
				 case 'C':
				 case 'D':
				 case 'E':
				 case 'F':
				 case 'G':
				 case 'H':
				 case 'I':
				 case 'J':
				 case 'K':
				 case 'L':
				 case 'M':
				 case 'N':
				 case 'O':
				 case 'P':
				 case 'Q':
				 case 'R':
				 case 'S':
				 case 'T':
				 case 'U':
				 case 'V':
				 case 'W':
				 case 'X':
				 case 'Y':
				 case 'Z':
					 return true;
				 default:
					 return false;
			 }
		 }
		 else
			 return false; 

	 }	
	
	
	 [MethodImplAttribute(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
	 public static bool isValidDriveLetterV5(this string drivewithcolon)
	 {
		 
		 if (drivewithcolon.Length == 2 && drivewithcolon[1] == ':')
		 {
			 drivewithcolon = drivewithcolon.ToUpper();
			 // this is surprisingly faster than the equivalent if statement
			 switch (drivewithcolon[0])
			 {
				 case 'A':
				 case 'B':
				 case 'C':
				 case 'D':
				 case 'E':
				 case 'F':
				 case 'G':
				 case 'H':
				 case 'I':
				 case 'J':
				 case 'K':
				 case 'L':
				 case 'M':
				 case 'N':
				 case 'O':
				 case 'P':
				 case 'Q':
				 case 'R':
				 case 'S':
				 case 'T':
				 case 'U':
				 case 'V':
				 case 'W':
				 case 'X':
				 case 'Y':
				 case 'Z':
					 return true;
				 default:
					 return false;
			 }
		 }
		 else
			 return false; 

	 }	

	[MethodImplAttribute(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
	public static bool isValidDriveLetterV6(this string drivewithcolon)
	 {
		 if (drivewithcolon.Length == 2 && drivewithcolon[1] == ':')
		 {
			 drivewithcolon = drivewithcolon.ToUpper();		 
			 if (drivewithcolon[0] >= 'A' && drivewithcolon[0] <= 'Z') 
			 	return true;
			 else 
				 return false; 
		 }
		 else
			 return false; 

	 }
 	
	public static void Main()
	{
	    bool v1,v2,v3,v4,v5,v6 = false;  

		Stopwatch sw = new Stopwatch(); 

		sw.Start();
		v1= "Z:".isValidDriveLetter(); 
		sw.Stop();
		Console.WriteLine("is Z: valid drive letter ?{0}, v1 in {1} ticks.",v1.ToString(), sw.ElapsedTicks);
		
		sw.Reset(); 
		sw.Start();
		v2= "Z:".isValidDriveLetterV2(); 
		sw.Stop();
		Console.WriteLine("is Z: valid drive letter ?{0}, v2 in {1} ticks.",v2.ToString(), sw.ElapsedTicks);
	
	    sw.Reset(); 
		sw.Start();
		v3= "Z:".isValidDriveLetterV3(); 
		sw.Stop();
		Console.WriteLine("is Z: valid drive letter ?{0}, v3 in {1} ticks.",v3.ToString(), sw.ElapsedTicks);
	
	    sw.Reset(); 
		sw.Start();
		v4= "Z:".isValidDriveLetterV4(); 
		sw.Stop();
		Console.WriteLine("is Z: valid drive letter ?{0}, v4 in {1} ticks.",v4.ToString(), sw.ElapsedTicks);
	
		sw.Reset(); 
		sw.Start();
		v5= "Z:".isValidDriveLetterV5(); 
		sw.Stop();
		Console.WriteLine("is Z: valid drive letter ?{0}, v5 in {1} ticks.",v5.ToString(), sw.ElapsedTicks);
	
		sw.Reset(); 
		sw.Start();
		v6= "Z:".isValidDriveLetterV6(); 
		sw.Stop();
		Console.WriteLine("is Z: valid drive letter ?{0}, v6 in {1} ticks.",v6.ToString(), sw.ElapsedTicks);
		
		
	}
}

Wednesday, October 28, 2020

Phishing Email from Paisley Hutchinson with subject Security Alert. Your accounts were hacked by a criminal group.

For the record, this is an Paisley Hutchinson phishing email attempt that is recently going around, with subject "Security Alert. Your accounts were hacked by a criminal group." What to do?  Report them, goto bottom of page. 


From : Paisley Hutchinson <support@algotrack.in> 

Subject
 : Security Alert. Your accounts were hacked by a criminal group.


Hello!

I am a professional coder and I hacked your device's OS when you visited adult website.
I've been watching your activity for a couple of months.

If you don't understand what I am talking about I can explain...
My trojan malware lets me get access to my victim's system. It is multiplatform software with hVNC that can be installed on phones, PC and even TV OS...
It doesn't have any AV's detects because it is encrypted and can't be detected becaause I update it's signatures every 4 hour.
I can turn on your camera, save your logs and do everything that I want and you won't notice anything.

Now I have all your contacts, sm data and all logs from chats for the latest 2 months but it is not very useful without something that can spoil your reputation...
I recorded your masturbation and the video that you watched. It was disgusting.

I can destroy your life by sending this stuff to everybody you know.
If you want me to delete this stuff and avoid any problems you have to send $1000 to my bitcoin address: 1FDVdXo5f7bCdiw6AijyQU2Hc9XcZ17Gia


If you don't know how to buy bitcoins use Google, there are a lot of manuals about using, spending and buying this cryptocurrency.

You have 50 hours from now to complete the payment.
I have a notification that you are reading this message... TIME HAS GONE.

Don't try to respond because this email address is generated.
Don't try to complain because this and my bitcoin address can't be tracked down.

If I notice that you shared this message everybody will receive your data.
Bye!




PHISHING LINKs;

1. support@algotrack.in 


How to tell this is a Phishing email ?

  1. Check email address in full, if it's not from originating company then it's phishing.
  2. Hover over all links in email, if it's not from the  company's website then forget it.
  3. The best way is to 

How to examine Email Message Source ?

Now lets look at message source
  1. Outlook.com->Actions->View Message Source. 
  2. Gmail.com->More (down arrow to top right)->Show original.
Check for suspicious links, anything that does not originate from apple.com.


Report Phishing Email (not as Spam)

  1. Outlook.com->Junk (at Top)->Phishing Scam
  2. Gmail.com->More (down-arrow to top right)->Report Phishing 

Report Phishing

If you have recievied this email take further 

  1. https://www.google.com/safebrowsing/report_phish/


Report phishing at Microsoft and government agencies

  1. http://www.microsoft.com/security/online-privacy/phishing-faq.aspx

Tuesday, October 27, 2020

Amazon Phishing Email - FWD: Important: [New-Noticed] : Your Account - Blocking Logged 25/10/2020 Available

For the record, this is an Amazon phishing email attempt that is recently going around, with subject "FWD: Important: [New-Noticed] : Your Account - Blocking Logged 25/10/2020 Available" What to do?  Report them, goto bottom of page. 


From : Amazon.com <5to4xxxx-xxxxxxx@bujanglapet.com> 

Subject
 : FWD: Important: [New-Noticed] : Your Account - Blocking Logged 25/10/2020 Available



Text for search engines 
---------------------------
Yo͏u͏r Ama͏z͏o͏n Ac͏c͏o͏u͏n͏t͏ a͏re on ho͏l͏d͏ due to a bil͏l͏i͏n͏g issue

Update Payment Information
Due to a problem with your card, we have been unable to charge your payment.

If you don't update your card information in the next 24 hours, your Amazon account are on hold permanently. To continue using your account, please visit this link to log in to your account and update your payment information.

Thank you,

Amazon.com Customer Service




PHISHING LINKs;

1. http://go.mollyiss.com/?COPGWAPMZL 


How to tell this is a Phishing email ?

  1. Check email address in full, if it's not from originating company then it's phishing.
  2. Hover over all links in email, if it's not from the  company's website then forget it.
  3. The best way is to 

How to examine Email Message Source ?

Now lets look at message source
  1. Outlook.com->Actions->View Message Source. 
  2. Gmail.com->More (down arrow to top right)->Show original.
Check for suspicious links, anything that does not originate from apple.com.


Report Phishing Email (not as Spam)

  1. Outlook.com->Junk (at Top)->Phishing Scam
  2. Gmail.com->More (down-arrow to top right)->Report Phishing 

Report Phishing

If you have recievied this email take further 

  1. https://www.google.com/safebrowsing/report_phish/


Report phishing at Microsoft and government agencies

  1. http://www.microsoft.com/security/online-privacy/phishing-faq.aspx

Monday, October 26, 2020

Never before undocumented command line switch /p for SnippingTool disclosed

Here's how to launch Snipping Tool in a non-interactive mode on start-up!

Interactive mode is where the entire screen freezes to snip a section with the mouse icon turned into a + plus icon. It's very annoying, the entire screen freeze, when you are not expecting it.

To disable interactive mode on start up and newly discovered (by me) /p switch. 

%windir%\system32\SnippingTool.exe /p

This is not an issue for Window 10 since it was turned off and you can use /clip to set rectangular mode. 

But still an issue for Windows 7.  

To use create a shortcut and add /p to the command line when you start the program.

 


This has been integrated into my (which run on Windows 7+), 

Clipboard PlainText PowerTool (CPPT) - the most advanced clipboard tool to date, 1 click to rule them all.





Friday, October 23, 2020

How to get microphone, webcam or speaker to work on older laptops with Windows 10 2004

Just thought I would share my experience about getting an older laptop and getting microphone, web cam or speakers to work with Windows 2004 Update.


I reinvigorated a Lenovo IdeaPad Z510, i5 with Windows 8 original installed and which was release in 2013, making it 7 yrs old. Try doing this with Android (Acer Iconia One 10 tablet lasted 1 year) or Mac OSes! (4yrs max). Good luck. All the software is still available at Lenovo Support Site.

The Z510 was speedily running Windows 10 1909 for awhile, then Update 2004 blew up the communications. Oh-oh dreaded driver issues?


In my situation in was the microphone. The webcam and speakers worked fine. This really stumped me since in the microphone and speakers use the same driver supplied by Realtek and it was installed and working. No driver issues reported, but the driver was 5 yrs. I reinstalled driver, to refresh it. No luck.










Then I remembered an old trick - turns out my default language was originally Canadian French,  then Canadian English, not US English.



Change all setting here to English, United States for Date & Time, Region, Language and Speech.


So I proceeded to change all setting to default U.S. English, see above image.

And voila, Cortana would work (did not complain that it was not supported in English (Canada) setting?) and microphone magically began to work. 

So when all else fails factory reset all setting to default US English. 

Hope this helps someone out. It's not an obvious solution.







Monday, October 19, 2020

C# .NET Get integer from hexadecimal string, many hex formats supported version 2
















The code below brackets the first likely hex number that matches, from the list of many hex formats that are specified with leading hex prefixes. Then it proceeds to remove prefixes and apply the TryParse functions. 

 
C# TryParse function with NumberStyles.HexNumber requires many hex prefixes to be removed first in order to works,  such as "0x". 

This will fail 
UInt32.TryParse("0x20", 
             NumberStyles.HexNumber, // AllowHexSpecifier - Strings that are parsed using this style cannot be prefixed with "0x" or "&h". 
             CultureInfo.InvariantCulture,  // I've also tried CurrentCulture
             out number));

//See https://docs.microsoft.com/en-us/dotnet/api/system.globalization.numberstyles?view=netcore-3.1#System_Globalization_NumberStyles_AllowHexSpecifier

Note: It is tempting to optimize first regex from
0x[0-9a-f]{2,}
to
0x([0-9a-f]{2,}) and use a group capture
but because we are capturing multiple expressions the overlap is troublesome. 


This is an update to my last post about this - 

C# .NET How to get integer from hexadecimal string, many hex formats supported


This code removes many hex formats prefixes as listed here - https://en.wikipedia.org/wiki/Hexadecimal


Source Code

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public static class Program
{

    const string strRegHexPrefixCandidates = @"0x[0-9a-f]{2,}|%x[0-9a-f]{2,}|\\u[0-9a-f]{2,}|&#x([0-9a-f]){1,6};|&#([0-9a-f]){1,6};|\\x[0-9a-f]{2,}|\\s[0-9a-f]{2,}|U\+[0-9a-f]{2,}|X'[0-9a-f]{2,}|16#([0-9a-f]){2,}|#x([0-9a-f]){2,}|#16r([0-9a-f]){2,6}|&H([0-9a-f]){2,}|0h([0-9a-f]){2,}|#([0-9a-f]){1,6}|%[0-9a-f]{2,}";
    const string strRegGetHexNumber = @"[0-9a-f]{2,}|[«‹»›„‚“‟‘‛”’""""❛❜❝❞〝〞〟"""""'‘][0-9a-f]{2,}[’'""""«‹»›„‚“‟‘‛”’""""❛❜❝❞〝〞〟"]";
    private static readonly Regex rgxHexPre = new Regex(strRegHexPrefixCandidates, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant | RegexOptions.Compiled);
    private static readonly Regex rgxGetHexAgressive = new Regex(strRegGetHexNumber, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
    public static void Main()
    {
        //string unicodeText = "UTF-16 (hex)	0x0023 (0023)";
        string unicodeText = @"In XML and XHTML, characters can be expressed as hexadecimal numeric character references using the notation &#xcode;, for instance &#x2019; represents the character U+2019 (the right single quotation mark). If there is no x the number is decimal (thus &#8217; is the same character).[3]";
        //string unicodeText = "8E2";
        //string unicodeText = "this is the end";

        string firstCandidateHexVal = string.Empty;
        
        //https://en.wikipedia.org/wiki/Hexadecimal --remove possible prefixes
        foreach (Match p in rgxHexPre.Matches(unicodeText))
        {
            if (p.Success) { 
                firstCandidateHexVal = p.Value;
                break;
            }
        }

        string prefixfree = string.Empty;
        if (!string.IsNullOrEmpty(firstCandidateHexVal)) 
        { 
            //same prefixes as in Regex
            string[] prefixHexs = new string[] { "0x", "%x", "\\u", "&#x", "&#", "\\x", "\\s", "U+", "X'", "16#", "#x", "#16r", "&H", "0h", "#", "%" };
            foreach (var pre in prefixHexs)
            {
                if (firstCandidateHexVal.IndexOf(pre) > -1)
                {
                    prefixfree = firstCandidateHexVal.Substring(firstCandidateHexVal.IndexOf(pre) + pre.Length);
                    break;
                }
            }
        }

        string finalHexCandy = string.Empty;

        if (string.IsNullOrEmpty(prefixfree))
            finalHexCandy = unicodeText;
        else  
            finalHexCandy = prefixfree;

        Match m = rgxGetHexAgressive.Match(finalHexCandy);
        bool success = false;
        ulong number = 0;
        string hex_value = string.Empty;
        
        if (m.Success)
        {
            try
            {
                hex_value = m.Value;
                //long number = Convert.ToInt64(hex_value, 16); //base 16 - hex....
                //https://stackoverflow.com/questions/2801509/uint32-tryparse-hex-number-not-working -> remove prefixes
                success = ulong.TryParse(hex_value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out number);
            }
            catch (FormatException)
            {
                unicodeText = string.Format("{0} is not in the correct format for a hexadecimal number.", m.Value);
            }
            catch (OverflowException)
            {
                unicodeText = string.Format("{0} is outside the range of an Int64.", m.Value);
            }
            catch (ArgumentException)
            {
                unicodeText = string.Format("{0} is invalid in base 16.", m.Value);
            }
            catch (Exception ex)
            {
                unicodeText = string.Format("{0} return error\r\n{2}", m.Value, ex.Message);
            }
        }
        else
            unicodeText = "Could not find a hex number in \"" + unicodeText + "\". Select the hex number only.";



        if (!string.IsNullOrEmpty(firstCandidateHexVal))
            hex_value = firstCandidateHexVal; 

        
        if (success)
            unicodeText = string.Format("{0} integer from found {1:N0} hex number in string: {2}", number, hex_value, unicodeText);
        else
            unicodeText = "Could not find a hex number in string: \"" + unicodeText + "\". Select the hex number only.";
        
        Console.WriteLine(unicodeText);
 
    }
}

Tuesday, October 13, 2020

C# .NET How to get integer from hexadecimal string, many hex formats supported















The aim of this post is to parse a hexadecimal number from a string using C# code. 

Using C# recommended TryParse function using the NumberStyles.HexNumber flag simply fails on many hex formats.

For example, "0x20" will fail?  

UInt32.TryParse("0x20", 
             NumberStyles.HexNumber, // I've tried also AllowHexSpecifier
             CultureInfo.InvariantCulture,  // I've also tried CurrentCulture
             out number));


The problem with NumberStyles.HexNumber is that it doesn't support parsing values with a prefix (ie. 0x, &H, or #), so you have to strip it off before trying to parse the value.

So the code below removes many hex formats prefixes as listed here  - https://en.wikipedia.org/wiki/Hexadecimal to enable the conversion to work, 


As per feedback, I improved the algo to first quarantine likely regex hex matches with prefixes then run another regex to extract the hex within that match.



 
Source Code

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public static class Program
{
	const string strRegGetHexNumber = @"\\u[0-9a-f]{2,}|0x[0-9a-f]{2,}|%[0-9a-f]{2,}|\u0023([0-9a-f]){1,6}|&\u0023x([0-9a-f]){1,6};|\s[0-9a-f]{2,}|[0-9a-f]{2,}|[«‹»›„‚“‟‘‛”’""""❛❜❝❞〝〞〟"""""'‘][0-9a-f]{2,}[’'""""«‹»›„‚“‟‘‛”’""""❛❜❝❞〝〞〟"]";
	private static readonly Regex rgxGetHex = new Regex(strRegGetHexNumber, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
	public static void Main()
	{
		string unicodeText = "UTF-16 (hex)	0x0023 (0023)";
		//https://en.wikipedia.org/wiki/Hexadecimal --remove possible prefixes
		string prefixfree = string.Empty;
		string[] prefixHexs = new string[]{"0x", "\\u", "#", "&#", "\\x", "\\s", "U+", "X'", "16#", "#x", "#16r", "&H", "0h"};
		foreach (var pre in prefixHexs)
		{
			if (unicodeText.IndexOf(pre) > -1)
			{
				prefixfree = unicodeText.Substring(unicodeText.IndexOf(pre) + pre.Length);
				break;
			}
		}

		if (string.IsNullOrEmpty(prefixfree))
			prefixfree = unicodeText;
		Match m = rgxGetHex.Match(prefixfree);
		bool success = false;
		ulong number = 0;
		string hex_value = string.Empty;
		if (m.Success)
		{
			try
			{
				hex_value = m.Value;
				//long number = Convert.ToInt64(hex_value, 16); //base 16 - hex....
				//https://stackoverflow.com/questions/2801509/uint32-tryparse-hex-number-not-working -> remove prefixes
				success = ulong.TryParse(hex_value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out number);
			}
			catch (FormatException)
			{
				unicodeText = string.Format("{0} is not in the correct format for a hexadecimal number.", m.Value);
			}
			catch (OverflowException)
			{
				unicodeText = string.Format("{0} is outside the range of an Int64.", m.Value);
			}
			catch (ArgumentException)
			{
				unicodeText = string.Format("{0} is invalid in base 16.", m.Value);
			}
			catch (Exception ex)
			{
				unicodeText = string.Format("{0} return error\r\n{2}", m.Value, ex.Message);
			}
		}
		else
			unicodeText = "Could not find a hex number in \"" + unicodeText + "\". Select the hex number only.";
		if (success)
			unicodeText = string.Format("{0} from found {1:N0} hex number in string {2}", number, hex_value, unicodeText);
		else
			unicodeText = "Could not find a hex number in \"" + unicodeText + "\". Select the hex number only.";
		Console.WriteLine(unicodeText);
	}
}