tag:blogger.com,1999:blog-83723910963097203172024-03-13T01:54:17.868-07:00My life behind the patchViews of a copy protection tourist.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.comBlogger32125tag:blogger.com,1999:blog-8372391096309720317.post-67191117181744531972020-08-12T22:26:00.002-07:002021-06-13T06:43:48.227-07:00All the platforms I've cracked for/on *UPDATED*<p> I saw a request for someone to remove a doc check in a Mac Classic app today, to which I volunteered. This made me think back to the amount of things I've cracked code on. I thought I should document that list somewhere, and maybe a story or two.</p><p><br /></p><p></p><ul style="text-align: left;"><li>As explained elsewhere on this blog, I started cracking on the Commodore 64. </li><li>Then cracked a couple of games on TRSDOS on the Radio Shack TRS-80 Model 3/4. </li><li>Then, I sold my C-64 stuff, and bought an Amiga. I cracked a few games there. </li><li>While at work one day, I got the opportunity to crack Empire! for my boss on DOS. </li><li>I cracked games on Windows.</li><li>I cracked an NLM module on Novell Netware once</li><li>I cracked an app for the Palm Pilot, so Palm OS</li><li>I've cracked Macintosh apps on 68k, PPC, and X86.</li><li>I cracked a "Pay to use" sound driver for Linux. (10k1 sound driver IIRC).</li><li>I "cracked" Super Star Wars on the SNES, as it wouldn't run on the Magicom</li><li>I cracked/keygened a Verifone Tranz 380x2</li><li>I cracked an app that ran on Windows CE on ARM.</li><li>I cracked an app that half ran on the PC, and the other half on an STM32F103. (Including dumping the code from the STM32, figuring out the protocol between the PC app and the device, and writing PC based code that emulated the whole mess without using the original PC app, or the device).</li></ul><div>I *BELIEVE* that's the complete list. Should anything else pop into my head, I'll be sure to come back and add them here. <br /><br />I rented a Mercedes C300 for a trip once, and when I tried to use the navigation, it told me that I needed to purchase a license for it. I also found that there was an SD card in the car with the navigation software on it. So, I took it out, WRITE PROTECTED IT, and copied the contents off to my PC. I then put the card back in the car, and returned it to the rental agency. When I got home, I looked at the navigation program that I had gotten from the card, and I was quite shocked to see that it was Windows CE based, and the registration stuff was in a .DLL. I tossed it into IDA, and finding the registration code, and finding the specific place to cause it to not CARE that it wasn't licensed, was pretty easy. I went online, and looked around, and there was, at the time, a message board dedicated to people that owned the C class, and there was a topic in it talking about the navigation, and having to buy a license. I asked if anyone would be willing to try my "modified" version, and a couple of people offered to give it a shot. I patched the .DLL, and posted a link on this board, people grabbed it, and told me that when they put it on the card, the car refused to even admit that there was anything in the card reader. So, I assume it was hashed somewhere or something. (That's how *I* would do it if I were trying to protect it). So, not having access to a head unit to pull the code from, that was the end of that investigation.<br /><br />I've long been fascinated with automotive head units, and the code that runs on them. I had a rental Genesis G80 once as well, and I did the same thing. Pulled the SD Card, and copied the code from it for examination. This was much better, as it's x86 Linux running QT apps. So, something that I wanted to know. This car featured Sirius XM radio, and I wanted to see where in the code it was handled. So, I went looking, only to find that the head unit code only handled status messages sent over the DBUS interface, from what I can only assume, is a self-contained module in the head unit. So, no code to look at there. And that's a shame, as Hyundai, or whomever makes the units, didn't strip the executables, so I got function names, and some variable names as well. It was easy to disassemble, read, and understand.</div><div><br /></div><div><br /></div><p></p>Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-86186516824447740032020-01-19T14:20:00.000-08:002020-01-19T14:21:25.906-08:00For the last(??) time, .NET code isn't safe!Recently a friend asked me to have a look at an application that he uses. So I downloaded and installed it, and set about having a look. A quick glance at the file listing shows a likely candidate, "Common.Licensing.dll". Could you be any more obvious? And the filesize? 30kb. (closes eyes, shakes head). I toss it into IDA Pro, and discover that it's a .NET assembly. So, I exit IDA, and toss it into dnspy. (If you've not yet seen the power of dnspy, I HIGHLY recommend it. This applies not only to us reversers, but to anyone who ships a protected product using .NET. Have a look at what I can see about your product!)<br /><br />For instance, if you have a licensing object, and associated fields, I might see something like this:<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<br /></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">int</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #248f8f; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">TrialDays</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> { </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">get</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">; </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">set</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">; }</span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">bool</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #248f8f; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">IsTrial</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> { </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">get</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">; </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">set</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">; }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
This means that I can simply replace the accessor functions to always say that this ISN'T a trial by returning FALSE on the get, and just ignoring what happens in the set. Or, if I'm feeling especially funny, I'll change the TrialDays get to return "69", or "420" or some other funny number. Or if you store the code that the user enters when trying to register your application in an obvious place, I might see something like this:<br /></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">string</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #248f8f; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">ActivationCode</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">get</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">return</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">this</span><span style="color: #b4b4b4; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">.</span><span style="color: red; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">_settings</span><span style="color: #b4b4b4; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">.</span><span style="color: red; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">ActivationCode</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> }</span></div>
<div>
<span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
So now I can just look through the rest of the code for references to ActivationCode, and find all sorts of things. Like, I could find out that you compute this activation code via MD5:<br /></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">GetHash</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">activationCode</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">, </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">email</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">, </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">bool</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">isExtended</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: red; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">LicenseChecker</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: red; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">GetMd5Hash</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #378d7b; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">CryptHelper</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #e67300; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Encrypt</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">this</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">GetHwId</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">isExtended</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">), </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">this</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Aggregate</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">new</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">[]</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">activationCode</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">,</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">email</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">,</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">this</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #aa70ff; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">_md5HashKey</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }, </span><span style="background-color: transparent; color: #d69d85; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">""</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">)));</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span id="docs-internal-guid-fca316b7-7fff-29a8-0fd4-d018e6b9c999"></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }
<span style="color: black; font-family: "Times New Roman"; font-size: small; white-space: normal;">But, you think that's OK, because you encrypt it before you store it, right? Like this: </span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #33ccff; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Func</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">, </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">> </span><span style="background-color: transparent; color: #248f8f; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Encrypt</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">get</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> (</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">value</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">) </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=></span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #378d7b; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">CryptHelper</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #e67300; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Encrypt</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">value</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">, </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">this</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: red; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">_md5HashKey</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">);</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><span id="docs-internal-guid-353c7b54-7fff-4436-79aa-e7c4b505f321"></span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I heard that! You said "Big deal, you know it's MD5, but you don't know the hash key! Ahem:
<span id="docs-internal-guid-bb09f802-7fff-2225-83a2-9f578f8fedfd"><span style="color: #569cd6; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">public</span><span style="color: gainsboro; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;"> </span><span style="color: #569cd6; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">readonly</span><span style="color: gainsboro; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;"> </span><span style="color: #569cd6; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">string</span><span style="color: gainsboro; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;"> </span><span style="color: #aa70ff; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">_md5HashKey</span><span style="color: gainsboro; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;"> </span><span style="color: #b4b4b4; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">=</span><span style="color: gainsboro; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;"> </span><span style="color: #d69d85; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">"kPW6ib49Q1mUaPJBmD2OKaXLo9B7eKCf"</span><span style="color: gainsboro; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">;</span></span>
</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span><span style="color: gainsboro; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;"><br /></span></span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">But, it's not all bad news! (I lied, it's all bad). Even your idea that "it's OK to include the code to compute the activation code locally, as you plan to VALIDATE it online, and THAT will certainly stop me" is a bad one. As you included all of THAT code in the same file, so it became this:
</span></span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">bool</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">CheckOnline</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">UserSettings</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">settings</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">, </span><span style="background-color: transparent; color: #33ccff; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Action</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">onOnlineReCheckFailed</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">null</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">, </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">bool</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">waitResult</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">false</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">{</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">true</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">}</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-4d782978-7fff-e761-3c56-0354a50e1620"></span><span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">
And that's just not very useful is it? You also started some threads that should, in theory, validate the activation from time to time right?
</span></span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">async</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Task</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">> </span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">CheckOnlineAsync</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">UserSettings</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">settings</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #009933; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">TaskAwaiter</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">bool</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">taskAwaiter</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">this</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">IsOnline</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">()</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">GetAwaiter</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">();</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">if</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> (</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">!</span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">taskAwaiter</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #248f8f; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">IsCompleted</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">await</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">taskAwaiter</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #009933; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">TaskAwaiter</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">bool</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">taskAwaiter2</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">taskAwaiter</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">taskAwaiter2</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">taskAwaiter2</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">default</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #009933; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">TaskAwaiter</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">bool</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">>);</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">result</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">if</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> (</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">!</span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">taskAwaiter</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">GetResult</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">())</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">result</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #bd63c5; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">ConnectionToServerFailed</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">else</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">url</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> (</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">!</span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">settings</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">IsValid</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">()) </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">?</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">this</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #aa70ff; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">_registrationURL</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">:</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">this</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #aa70ff; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">_checkURL</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">requestData</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">this</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">GetRequestData</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">settings</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">);</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">result</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">await</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">this</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">GetServerResult</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">url</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">, </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">requestData</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">, </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">false</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">);</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">result</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-f3b170d3-7fff-823f-deaf-27befa986b79"></span><span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">Well, I see from this that you return an enum. And, you include that in the source, so this whole function becomes:
</span></span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">async</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Task</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">> </span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">CheckOnlineAsync</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">UserSettings</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">settings</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #bd63c5; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SuccessfullyValidated</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-3de2646c-7fff-5783-8b84-17460fcb84c7"></span><span><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline;">And you included, as strings! The server URLs that you plan to try to contact, have all been changed. This is what they look like now:
</span></span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">readonly</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #aa70ff; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">_registrationURL</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #d69d85; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">"localhost"</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">readonly</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #aa70ff; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">_checkURL</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #d69d85; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">"localhost"</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">readonly</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #aa70ff; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">_trialURL</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">=</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #d69d85; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">"localhost"</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">So, good luck getting any data out that way either.
And last but not least, all those other "background tasks" that you run that will validate things, and update member variables of the class should something not look right? Yeah, they don't do much anymore:
</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">async</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Task</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">> </span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">CheckTrial</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #bd63c5; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SuccessfullyValidated</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b id="docs-internal-guid-08318033-7fff-d0a4-70af-6ce9b4fd0ed2" style="font-weight: normal;"><br /></b></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">async</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Task</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">> </span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">CheckAsync</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">activationCode</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">, </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">email</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #bd63c5; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SuccessfullyValidated</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">async</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Task</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">> </span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">CheckAsync</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">UserSettings</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">settings</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #bd63c5; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SuccessfullyValidated</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b id="docs-internal-guid-dafb5012-7fff-9e34-6451-73f2e0d05638" style="font-weight: normal;"><br /></b></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">async</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #4ec9b0; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Task</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><</span><span style="color: #b8d7a3; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">SerialValidationResultEnum</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">> </span><span style="color: #ff8000; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">GetServerResult</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">(</span><span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">string</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: darkkhaki; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">url</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">string</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: darkkhaki; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">requestData</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">bool</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: darkkhaki; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">isTrialResponse</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #b4b4b4; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">=</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="color: #569cd6; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">false</span><span style="color: gainsboro; font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SerialValidationResultEnum</span><span style="background-color: transparent; color: #b4b4b4; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">.</span><span style="background-color: transparent; color: #bd63c5; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SuccessfullyValidated</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><b style="font-weight: normal;"><br /></b></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">async</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Task</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">bool</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">> </span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">IsOnline</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">false</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">async</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #4ec9b0; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">Task</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"><</span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">bool</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">> </span><span style="background-color: transparent; color: #ff8000; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">SendAnalytics</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">(</span><span style="background-color: transparent; color: #b8d7a3; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">AnalyticsEventsEnum</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: darkkhaki; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">analyticsEvent</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">true</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-79437711-7fff-7b1a-0a7b-3777810cb78e"></span>
</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">And, as the cherry on this sundae of fail, I couldn't resist a little graffiti. </span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">public</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">string</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #248f8f; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">ActivationCode</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">get</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> {</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #569cd6; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">return</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> </span><span style="background-color: transparent; color: #d69d85; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">"The Humble Guys!"</span><span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;">;</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-45977cf2-7fff-e944-068b-c2a247aba971"></span></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: gainsboro; font-family: Arial; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; white-space: pre;"> }</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
This shows up when you do Help|About. <br /><br />So, in closing, be aware of your surroundings. If you plan to write an app in .NET be aware that there are some KICKASS tools out there for decompiling your code, and in the case of dnspy, it even allowed me to make all those changes you see above in a "Visual Studio feeling" editor, and one click later, it had compiled all my changes, and had written them to MY version of Common.Licensing.dll. So, no hex-editing required.</div>
Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-73364658188667348852019-11-07T08:47:00.001-08:002020-01-19T10:50:54.111-08:00*35th Anniversary of cracking/reversing*Has it really been that long? This post will be different from my normal posts, in that it'll contain very little technical content.<br />
<br />
I'd like to take this opportunity to thank the people who nurtured my obsession along the way, and remember the fallen friends that I met as a result.<br />
<br />
As detailed elsewhere on this blog, I fell into cracking copy protection literally by accident. A well timed "Run/Stop Restore" press on my late best friend's Commodore 64 got me past the disk check on "Scrolls of Abadon" by Access software. A short while later, Darren "Dr. Who" from Donelson Tennessee showed me how to crack Raid on Bungling Bay by NOP'ing a couple of bytes, and the ball was rolling. Here we are 35 years later. I've cracked software on all sorts of platforms. C-64, Amiga, TRS-80, DOS, Windows, Linux, some embedded products that ran NO OS. It's been a helluva ride, and I've MOSTLY enjoyed the experiences. It's amazing to me that we've come to the point that cracks on new Denuvo protected games can only be done by a couple of people, and in some cases can take A YEAR. When I first cracked Rob Northen's Copylock, it took me a MONTH, and that seemed to be both forever, and the lamest thing in the history of the world. So much so that I wrote a tool to automatically remove it from all titles in the future. And I remember when cracking Ultima 6 took ALL DAY. A full 8 hours at work was spent crawling through the code until I finally found a single "TEST" instruction that made the difference. If the test failed, it would ask you the doc check question, whereas a pass would skip it.<br />
<br />
My most recent crack was last night. I did an E-Commerce management app. It was a trial that would pop up a nag every X seconds. It fully worked, but it just nagged you. Written in one of the Borland languages, it was a slight challenge as the string handling wasn't normal. It didn't use static strings in the executable, nor did it use strings in the resource section either. It was some weird Borland specific DKLang thing. But ultimately, it was the call to MessageBox that did them in. That lead me right back to the code that was showing the box, which was in a function triggered by a timer message arriving on the main thread. A quick RETN, and all was right in the world again.<br />
<br />
So, in closing, I'd like to call out my departed friends who meant so much to me during this run.<br />
<br />
Michael Todd Jackson - Had it not been your willingness to let me hack around on your C-64, your encouragement, and your friendship, none of this would ever have happened. I miss you as much today as I did the day you passed. I'm still dancing my friend.<br />
<br />
Dave Francis (Candyman) - Had it not been for your connections, THG would never have happened, and no one would know who I am, or care. Thanks for all the time, and money you spent on this hobby that we did "so that we could be popular with 15 year olds using daddy's PC."<br />
<br />
Rick Cook (Mongo) - Thanks for your constant friendship and encouragement through the years my friend. I hope everything is better for you now. The ghosts of traumas past are finally gone, and you can be at peace. See you (relatively) soon my friend.<br />
<br />
Pierre Barkett (PieMaN) - Thanks for your friendship, dedication to THG, and for taking one for the team with the Novell raid. You were a good dude, and I'll never forget you.<br />
<br />
And now, on to the next 35 years!<br />
-FabFabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com1tag:blogger.com,1999:blog-8372391096309720317.post-5818749052426264342019-03-30T18:50:00.003-07:002020-01-19T10:52:46.967-08:00Yet another peril of off the shelf copy protectionA friend contacted me to "help him with a program". That can only mean one thing, "can you fix this for me?". He sends it along, I install it, and start looking at the files that I get. Right away I notice something suspicious. There's a .dll in here named "KEYLIB32.DLL". Could you be any more obvious? A quick check of the version info confirms that it's from a different company from the target, and a quick Google points me at them. I toss the main app into IDA, and when the disassembly is done, I look at the imports to see that all the functions called from keylib32 are things that just SOUND like copy protection. I save the disassembly, and toss keylib32 into IDA. "Import section destroyed" (or something similar). Huh, is this PACKED? I fire up some "protection and packer identifier" apps, and see that it IS packed. With a packer made by the same company that makes keylib32 itself. NICE! At this point I'm thinking "This could be hairy if they really know what they're doing". (But how many people truly do?)<br />
<br />
I run the app for the first time, get presented with the typical "You don't have a license, what do you want to do?" style dialog, I choose "activate" of course, and then "activate by phone" so that it won't attempt to connect to anyone over the internet. It provided 2 numbers for me, and asked for 2 numbers FROM me. I enter some BS as I normally do, and press "Next", and it pops up a nice messagebox telling me that code 1 was incorrect. That's almost ALWAYS helpful. I flip over to IDA, and search for that string. What do you MEAN not found? I search for smaller parts, nothing! I fire up hexworkshop and search the .exe for the string in either ascii or unicode. Not there. Huh. I've seen this before! Some authors of apps will put all their strings in an external .DLL to make the app easier to port to other languages. They just recreate the app with the translated strings and the correct "resource IDs", and boom. It's done. So now, the search is on for the .DLL. It's not hard to find, and a few minutes with Resource Hacker and I have the resource IDs for the dialog box, and the error strings for when things go bad. A quick search for the dialogs resource ID, and I discover that there are WAYY too many instances of this value in the program. I need a new tact. So, instead, I search for CDialog::CD, and this walks right through the app, pointing out every place that a dialog is created, or DoModal is called to handle it. A minute or so of this searching takes me right to the code that creates, and calls the dialog. A quick look at the code before it shows what must be the "Do you have a license file?" code. A quick 5 byte change, and the jnz is now a jmp, and we can skip the "You don't have a license, what do you want to do?" dialog, and use the program. I give this patch to my bud, as he was in a bit of a crunch, and now with the pressure off, I had some time to do a deeper dive into this protection.<br />
<br />
I went looking for an automated unpacker that would unpack that .DLL, and let me look at the guts of the functions. No go. So, I turned to Google. There was no "pirate chatter" about the protection, but there was something better. A website with the full SDK documentation for it. The same stuff you'd get if you were Johnny shareware author and you'd just wasted your money on this crap. A few minutes of reading what the individual APIs did, and it seemed simple enough. I went back to IDA's imports tab, and found the especially interesting sounding ones that got called, and looked them up. Hmm. This one is interesting! pp_eztrig1ex(). This appears to be the function that gets called when you press "Next" on the button I mentioned above. This is the muscle that does the actual comparison of what you typed in, vs. what was expected. This could be useful! I jumped to where the stub was in the app, and saw that there was *1* reference to this function. That's handy! I went to that location, and fired up HexRays to give me a shortcut peek into what I was dealing with. Lots of functions, lots of compares, and best of all, references to those error strings I found in the resources earlier! We're definitely close! I found the compare for the return value from the the checker function, and forced it to pass. (Sometimes this will cause the app to generate a valid license and save it for you, effectively self-registering, and that's the end). In this case though, it wasn't to be. I got the "Congrats, your shit is registered" dialog box, but I also got a "This is an unregistered eval copy" message at the bottom of the app. Well THAT'S no good! I figured I should take a closer look at this protection, and see if I could find any hints.<br />
<br />
My first thought was that I could read the documentation, and see if they showed how you were supposed to write your own key generator. As it turns out, you DON'T. They HAVE one. It comes with the SDK. To their benefit, they didn't have a "Here, please download our SDK!" link in sight. This would have been almost too embarrassing for words. Another quick Google search, and I have a link to TFEdit. The generic keygen app for people using this protection. I fire it up, and some idiot has left their info in it. So, I could generate licenses for their apps all day. (shakes head). I then go BACK to the online documentation, and research how to set up a new application. It turns out that as a developer, the ONLY things that differentiate YOUR codes from MY codes are 2 keys. We'll call them seed1, and seed2. (As that's more or less what THEY call them). I tinker around, and find out that seed2 has to be between 1-254. Now that's REAL security right there! seed1 appears that it COULD be larger. So there we have it, we need to know the seeds that are used to generate these licenses. I could brute force this, but that would take longer than I was willing to invest in this crap. So, I went back to the documentation for our friend pp_eztrig1ex, and it reveals:<br />
<br />
LONG pp_eztrig1ex(PPLFHANDLE handle, LONG regkey1, LONG regkey2, LONG flags, LONG usercode1, LONG usercode2, LONG tcseed, LONG regkey2seed, LPLONG tcvalue, LPLONG tcdata)<br />
<br />
Arguments:<br />
<br />
<handle>handle is the handle to the License File given by pp_lfopen()</handle><br />
<br />
<regkey1>regkey1 is the value of Reg Key 1 entered by user</regkey1><br />
<br />
<regkey2>regkey2 is the value of Reg Key 2 entered by user</regkey2><br />
<br />
<flags>flags is reserved; set to 0 always</flags><br />
<br />
<usercode1>usercode1 was used as User Code 1 or Session Code</usercode1><br />
<br />
<usercode2>usercode2 was used as User Code 2 or Computer ID</usercode2><br />
<br />
tcseed <b><tcseed>is the Trigger Code seed used to randomize the algorithm</tcseed></b><br />
<b><br /></b>regkey2seed <b><regkey2seed>is the Trigger Code Event Data seed</regkey2seed></b><br />
<br />
<tcvalue>tcvalue is a buffer to place the Trigger Code number. Use 0 to ignore this parameter.</tcvalue><br />
<br />
<tcdata>tcdata is a buffer to place the Trigger Code Event Data. Use 0 to ignore this parameter.</tcdata><br />
<br />
Yes, that's right. The call to the function passes BOTH seed values as parameters. I load up our old friend Olly, go to the location of that function call and set a breakpoint. Run the app, enter some crap, and press "Next", and we break. Huh, seed2 is, as expected, 1 byte. And seed1, the super secure one, is 2 bytes. I plug these values into my "new product setup" in TFEdit, and generate myself a license. The target app takes it, and says I'm registered. I exit it, and relaunch it, and it runs, but pops up a messagebox telling me that my support has expired, and that I *MUST* renew it. Huh, what is this? Well, it turns out that the license has 2 parts. 1 just unlocks that app, and the other specifies the number of days left on your support contract. (seed2 is used to "protect" those days). I run it again, re-enter the license details into the app, and this time specify the "extra data" as the max, 53 years of support, and generate the license. The target gobbles it down, and a restart reveals that I now have support as well. <br />
<br />
So, you pay $700 I think it is, for this protection package, and your only protection is 24 bits of data. And to make matters WORSE, they must be included in your app where any hacker can just extract them, and then use the license generator to make licenses. SAD, just SAD.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-45844411091741659682018-07-12T17:13:00.001-07:002018-07-12T17:13:19.225-07:00*sigh* People are still doing this...I just made a "registration tool" for an app that a friend asked me to look at for him. It was compressed/encrypted with some weird version of TeLock, and I was unable to find an automated tool/script that would unpack it. I saved it from memory, fixed the IAT, and then tossed it into IDA Pro to have a look. Using the Hex-Rays plug-in, this is the code I found for the all important function:<br />
<br />
int __thiscall ValidateEnteredCode(void *this)<br />
{<br />
void *_this; // ebp@1<br />
char *workBuffer; // edi@1<br />
unsigned int counter; // esi@1<br />
int character; // ST14_4@2<br />
int result; // eax@3<br />
int currentUser; // eax@4<br />
int data; // [sp-194h] [bp-194h]@1<br />
int digest; // [sp-188h] [bp-188h]@1<br />
int context; // [sp-168h] [bp-168h]@1<br />
int computedCode; // [sp-100h] [bp-100h]@1<br />
int enteredCode; // [sp-80h] [bp-80h]@3<br />
<br />
_this = this;<br />
readSIDsFromRegistry(this, this);<br />
sha256_init(&context);<br />
sha256_update(&context, &data, 12);<br />
sha256_final(&context, &digest);<br />
workBuffer = &computedCode;<br />
counter = 0;<br />
do<br />
{<br />
character = *(&digest + counter);<br />
workBuffer += sprintf(_this, workBuffer, "%02X");<br />
++counter;<br />
}<br />
while ( counter < 32 );<br />
getEnteredCode(_this + 152, &enteredCode, 128);<br />
result = strcmp(&computedCode, &enteredCode);<br />
if ( !result )<br />
{<br />
currentUser = getCurrentUserKey(_this);<br />
saveRegKey(*(currentUser + 4), _this);<br />
MessageBox(_this);<br />
result = endDialog(_this);<br />
}<br />
return result;<br />
}<br /><br />I renamed the functions, and variables after a little study, and some of the code output isn't 100% correct, (like the weird sprintf syntax), but there's enough here to illustrate what I'm talking about. The read the user SIDs from the registry into a buffer, and then hash the buffer, sprintf it into a string of characters, and then STRING COMPARE it against what you typed in. <br /><br />D U M B!<br />
<br />
Why is it dumb you ask? Well, to make my keygen for this, I used an old tool from 2000 called the Risc Process Patcher. It loads a program, and watches for memory locations to change from a specified value TO a specified value, and then applies patches that you provide. It's a very simple, and ultimately, a very USEFUL tool. I've used it since 1999 or so for just such things. So, back to this target. Using RPP, I had it watch for the "getEnteredCode" code to be unpacked/decrypted. Once it was, I just pushed the necessary values onto the stack, and called MessageBox to print out the "Correct" registration code for this machine/user. You write down what's in the MessageBox, and press OK, and the application crashes, and exits. (Yes, I could have made it cleaner, but the GAFs were low). You then run the regular app again, and just enter the correct code it just gave you, and boom. Registered. <br /><br />If you are going to write a registration routine, do a few minutes more studying, and do something that's not clearly so stupid. If you are computing the correct code in such a way that I could read it from memory, and enter it to bypass your registration routine, then you're doing it wrong.<br /><br />Some quick notes. Another reason that I did it the way that I did was that there was something weird going on. If I entered too big of a patch, when you ran the loader, it would load the executable and patch the code in the correct place, but the app would then crash somewhere else, totally unrelated. This could have been the unpacker catching it, or something else, but I shrunk my patch down to just what I told you above, and it worked fine. My 1st patch just changed what MessageBox printed. But that crashed, even before it got to the code. But, in the end, I was able to find the right balance between "tell me what I need to know", and "not crashing the app". <br /><br />And, as they used to say in the movies, all's well that ends well.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-26970545042535862382015-11-01T11:37:00.002-08:002015-11-15T21:22:05.442-08:00 Embedded Linux based internet appliance keygen - Follow up!The publisher of the software package that I mentioned in a previous post entitled " Embedded Linux based internet appliance keygen" just published an update. So, I grabbed the pertinent file (the shared object) and threw it into IDA. A quick cursory glace shows that in one aspect they STILL haven't learned their lesson. As they still don't strip it before shipping it. So, all the important functions "VerifyKey" "IsTrialKey", etc. are still labeled automatically by IDA. And it looks like their algorithm is still the same for computing the keys.<br />
<br />
BUT! Maybe they've learned something. Now, when you enter a key, they package it up, and send it to their webserver for verification. How do I know this? Simple! There's now a function called "SendActivationRequest". And, a quick spin through that function shows that it builds a nice URL, with a hashed component, and the normal sections for serial number, etc. Then, they use libcurl to send this to themselves for verification.<br />
<br />
Could I whack this step, and make it always assume that it succeeded? Sure, but the truth is. There's NO WAY, short of a FULL tracing of all the possible code paths, to know that they don't send this data somewhere else, at some random time. And, since this isn't a "warez" release for the world, and just a mod for some friends, I don't want to be responsible for them getting in trouble for using it. So, I'm not going to touch this new version.<br />
<br />
The device that this code runs on, HAS to be connected to the network, and in some cases, the internet. So, short of blocking all the companies IPs/domains in the firewall, you just can't be sure.<br />
<br />
Lastly, they now appear to have *2* blacklists for unauthorized serial numbers. The normal "compile time" one. (list of them is in the .so itself), and they also now have a list on their server. How do I know this? Maybe it could be because of the function called "UpdateOnlineBlacklist". <br />
<br />
So, there you have it. Some people DO pay attention, and learn, while others do the same thing over and over. Or worse yet, rely on some 3rd party to do it for them.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-21538824637053407342015-07-08T17:29:00.002-07:002016-03-06T16:43:01.107-08:00Who bases their product on Mozilla? (I mean, OTHER than Firefox?)Today's entry is a nameless application that's based on Mozilla's framework. I'm not sure WHY they did it this way, but it posed some interesting challenges. To start with, the initial application launcher didn't appear to actually DO anything, and then exited. I can only assume it did some sort of magic behind the scenes to kick off the application, and then it exits. It's very small, so I guess that's all it NEEDED to do. What was kinda interesting, is that it was named the same name as the main executable. So, if you looked at a task list, you would assume it was the launcher, and not the main application itself.<br />
<br />
Once I found the main application, I threw it into IDA like normal, and that reveals nothing worthwhile from the outset, but running it with "Break on DLL load" was VERY informative. The program loads the usual suspects, and then loads yet ANOTHER xxlicense.dll. (Name changed to protect the innocent). I exit the application, and go find xxlicense.dll. Turns out, it's a screaming 23KB. At least the LAST target attempted to thwart me by putting their licensing code in a HUGE .dll to make it harder to locate the pertinent bits. Not so this time. It's all right there in black and white. Sorta. So, I toss that file into IDA, it disassembles nicely, and I figure I'll just go to the exports list, and find the functions that I'm interested in, and start there. To my surprise, the exports list is almost empty. It contains 2 entries: DllEntryPoint, and NSModule. I've seen this sort of thing in the past when I was tinkering with a COM object's .dll. So what's going on here? Well, Mozilla has it's own list of methods that it uses, and IDA doesn't know about them. (Or at least *I* don't know how to make IDA know about them.) Either way. So, no hints about what the functions are named. We'll have to do it the hard way. I open the file in Hex Workshop, and examine the strings contained inside. There are lots of good ones! I pick a nice one like "'License file ',27h,'%s',27h,' does not exist',0". Go back to IDA, search for it, and boom. I now have a pointer back to where the license file is opened. A careful study of the function shows that it simply opens the file, and calls fgets in a loop to read all the contents into a buffer, after which, it closes the file. Using IDA's cross reference feature, I see that this function is called from *1* place. I go to that function, and see that it reads the license file into a buffer, and then passes the buffer to a function that processes it.<br />
<br />
It appears that the "fields" in the license are all text, separated by bar "|" characters. So, there is code to find the first bar, and copy from that point to the end of the license, to a new variable. They then pass a pointer to this buffer to another function. <br />
<br />
In the text area, there are some strings of garbage that aren't ASCII strings. This always makes me suspicious. In this case, it was warranted. We have this:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">loc_72AD1730 r</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD7061 db 0E0h ; a</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD7062 db 0E6h ; µ</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD7063 db 0F7h ; ˜</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD7064 db 0E0h ; a</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD7065 db 0F1h ; ±</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD7066 db 0EEh ; e</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD7067 db 0E2h ; G</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD7068 db 0E7h ; t</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD7069 db 0EEh ; e</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD706A db 0E0h ; a</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.data:72AD706B db 0FCh ; n</span><br />
<br />
The 1st character of that "string" is accessed inside the function that I'm looking at. It's copied to a buffer, and then there's code that decrypts it. It's simply XOR'd with 0xA5. So, looking at the result yields "SECRETKGBKEY". :-) Funny guys!<br />
<br />
They have that at the start of their buffer, and then copy the rest of the license over to it. Once they have it all in the same place, they run a simple MD5 against it. They save off the resultant hash, and return. The produced hash is then compared against the 1st "field" of the license they read in from the file. (The data before the 1st bar). If it matches? Code is GOOD!<br />
<br />
There is one last thing that they do. Inside the license text is a VERSION of the product. "Product9" or "Product5". Even though the hash matches, that doesn't mean that this license is for this version of the product. So, they compare it. (After they decrypt it that is!). So, to keep you from just reading the strings from the .dll, and knowing what to put in the file, they make you work a LITTLE harder.<br />
<br />
The product version string is stored with the high bit set, so that makes it also not a visible string when you look for it. There is a loop that grabs a byte from this "string", ands it with 0x7F, and then compares it to a character from your license. If they match, it goes on. Otherwise, the return value is the same as your run of the mill strcmp. (-1, 0, 1). Once you product string matches, you're good to go! <br />
<br />
One thing you have to be on the lookout for, it expects the LETTERS in your hash to be LOWERCASE. Uppercase will cause the compare to fail. <br />
<br />
So, the steps to make a license. Take an existing license (Maybe even from another product from the same company!), change the product name to match what you find in the .DLL. Replace the hash in the 1st field with SECRETKGBKEY. Generate an MD5 hash on that, and replace SECRETKGBKEY with the hash. Save, and enjoy your product!<br />
<br />
<br />
<br />
<br />
<br />
<br />Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-20377641632038011262015-07-05T16:18:00.001-07:002017-04-28T13:04:32.917-07:00Embedded Linux based internet appliance keygenA friend contacted me to tell me that an internet appliance that we both own has some extra functionality in it, if you enable it by entering a key code. Of course you know that means that I'm interested. The fact that said appliance is Linux based makes it more special for me, being a Linux hacker at heart. He sends me some screenshots of the webpages involved, and I start grepping for the strings that I see in the pictures. I find them, in a strings file. (Since this app is localized to many different languages, this is to be expected). I then search for references to that string ID. And find them in a javascript file. Of course it's compressed like those JS programmers do. So, I go to my favorite online JS beautifier site, paste the code in, and viola! I have readable code. A quick search with a text editor, and I'm looking at where the "Invalid code entered" box is displayed. And, I see that it's just a response to an error code. Some tracing back through the other JS files brings me to a call to a function. A quick grep for that function tells me that it's not in the JS anymore. Sounds like we're going in the right direction.<br />
<br />
I back out of the JS directory, and find the directory where the .so libraries are stored. A quick ls of the directory shows me a file called xxlicense.so. (Name has been changed to protect the innocent). I toss that into IDA Pro, and see that there are some functions here, but that they call to some centralized function not present in this file. The list of libraries that this thing loaded was impressive! The normal ones for glibc, and the like, but also a TON of other libraries. Not sure if they used them all, or if they were just trying to obfuscate where the protection bits were. So, I start loading the libs, one at a time, looking for where the functions were that it was calling. I FINALLY find them in a very large library. A little digging around shows me that in typical Linux style, they didn't strip the symbols from the library, so not only do I have the names for the EXPORTED functions, but I also have the names of the utility functions used by the exported functions. A little digging reveals verifyKey. A cursory glance through here is initially intimidating. OpenSSL, SHA1, big nums, etc. All the makings for a genuine nightmare. But, since you're reading about it here, you know where this is going.<br />
<br />
Some further study reveals that the unlock code that you enter is 20 characters long. They have a list of allowable characters. (No 0's, O's, 1's, l's, or anything that could be construed as being something else). <br />
<br />
<span style="background-color: white; color: purple; font-family: "courier new"; font-size: 10pt;">char</span><span style="background-color: white; font-family: "courier new"; font-size: 10pt;"> </span><span style="background-color: white; font-family: "courier new"; font-size: 10pt;">validCharacters</span><span style="background-color: white; color: maroon; font-family: "courier new"; font-size: 10pt;">[]</span><span style="background-color: white; font-family: "courier new"; font-size: 10pt;">=</span><span style="background-color: white; font-family: "courier new"; font-size: 10pt;"> </span><span style="background-color: white; color: maroon; font-family: "courier new"; font-size: 10pt;">{</span><span style="background-color: white; color: teal; font-family: "courier new"; font-size: 10pt;">"BCDFGHJKMPQRTVWXY2346789\0"</span><span style="background-color: white; color: maroon; font-family: "courier new"; font-size: 10pt;">}</span><span style="background-color: white; font-family: "courier new"; font-size: 10pt;">;</span><br />
<span style="background-color: white; font-family: "courier new"; font-size: 10pt;"><br /></span>
These characters are processed one at a time, and a pseudo-summation is performed to generate a key. The key contains some data, and a checksum of the key. My mock up of their code looks like this:<br />
<div style="background-color: white; font-size: 10pt;">
<pre><span style="font-family: "courier new";"> counter = </span><span style="color: navy; font-family: "courier new";">0</span><span style="font-family: "courier new";">;
</span><span style="color: purple; font-family: "courier new";">do</span><span style="font-family: "courier new";">
</span><span style="color: maroon; font-family: "courier new";">{</span><span style="font-family: "courier new";">
</span><span style="font-family: "courier new"; font-weight: bolder;">BN_mul_word</span><span style="font-family: "courier new";">(pOutput, </span><span style="color: navy; font-family: "courier new";">24</span><span style="font-family: "courier new";">);
keyCharacter = pInput</span><span style="color: maroon; font-family: "courier new";">[</span><span style="font-family: "courier new";">counter</span><span style="color: maroon; font-family: "courier new";">]</span><span style="font-family: "courier new";">;
compareCharacter = </span><span style="color: teal; font-family: "courier new";">'B'</span><span style="font-family: "courier new";">;
innerLoopCounter = </span><span style="color: navy; font-family: "courier new";">0</span><span style="font-family: "courier new";">;
</span><span style="color: purple; font-family: "courier new";">while</span><span style="font-family: "courier new";"> ( keyCharacter != compareCharacter )
</span><span style="color: maroon; font-family: "courier new";">{</span><span style="font-family: "courier new";">
++innerLoopCounter;
</span><span style="color: purple; font-family: "courier new";">if</span><span style="font-family: "courier new";"> ( innerLoopCounter == </span><span style="color: navy; font-family: "courier new";">24</span><span style="font-family: "courier new";"> )
</span><span style="color: maroon; font-family: "courier new";">{</span><span style="font-family: "courier new";">
innerLoopCounter = -</span><span style="color: navy; font-family: "courier new";">1</span><span style="font-family: "courier new";">;
</span><span style="color: purple; font-family: "courier new";">break</span><span style="font-family: "courier new";">;
</span><span style="color: maroon; font-family: "courier new";">}</span><span style="font-family: "courier new";">
compareCharacter = validCharacters</span><span style="color: maroon; font-family: "courier new";">[</span><span style="font-family: "courier new";">innerLoopCounter</span><span style="color: maroon; font-family: "courier new";">]</span><span style="font-family: "courier new";">;
</span><span style="color: maroon; font-family: "courier new";">}</span><span style="font-family: "courier new";">
++counter;
</span><span style="font-family: "courier new"; font-weight: bolder;">BN_add_word</span><span style="font-family: "courier new";">(pOutput, innerLoopCounter);
</span><span style="color: maroon; font-family: "courier new";">}</span><span style="font-family: "courier new";">
</span><span style="color: purple; font-family: "courier new";">while</span><span style="font-family: "courier new";"> ( counter != length );</span></pre>
<pre><span style="font-family: "courier new";">
</span></pre>
There are 24 characters in their "safe list". That's why there's a comparison of innerLoopCounter and 24. The 1st character of their list is 'B'. That's why they "pre-load" B into compareCharacter.<br />
Now, as you see, they don't add the CHARACTER to the sum, they add the INDEX of the character in their
"safe list". And then, multiply the whole thing by 24. (Except for the LAST character).
Being that the code is 20 characters long, this yields a valid number in the 46-91 bit
range. That's why they use the BN (Big Number) functionality from OpenSSL.
Once this is done, they then slice, and dice the results. The upper 45 bits are a SHA1 hash of the lower 46 bits.
And the lower 46 bits contains 31 bits of serial number, and 4 bits of license count, and 11 unused bits.
Since we understand all of this, we simply need to do things in the REVERSE order to make our keygen.
So, we take a serial number, and number of licenses, and shift those into place. Generate a SHA1 of that half,
truncate it to 45 bits, and slap it into the TOP half. THEN comes the interesting part.
Reversing the function you see above. It took me a while to figure out exactly how to do it,
since brute forcing 24^19th didn't seem like something that I would like to do on a regular
basis.
The way that I came to understand what would be the final technique was to start with a code of
00000000000000000001. I looked at the output.
Then, I moved the 1 to the left, like this: 00000000000000000010. Looked at THAT value.
I did that all the way across, and examined the values.
It came out as 1 * 24 ^nth. (Where nth represents the position of the 1 character in the string).<br />
<br />
This triggered a thought.
What if we do the LEFT most character first. And by DO, I mean divide it by 24^19th, use the result as the
index into the character array, and then work on the remainder.<br />
<br />
So, I whipped up code to do that.
It looks like this:
<br />
<div style="font-size: 10pt;">
<pre> <span style="color: green; font-style: italic;">// Set the divisor to 24^19</span>
<span style="font-weight: bolder;">BN_set_word</span>(result, <span style="color: navy;">24</span>);
<span style="font-weight: bolder;">BN_set_word</span>(remainder, <span style="color: navy;">19</span>);
<span style="font-weight: bolder;">BN_exp</span>(rollingDivisor, result, remainder, ctx);
<span style="color: green; font-style: italic;">// Process each digit (codes are 20 digits long)</span>
<span style="color: purple;">while</span> ( <span style="color: #c04000;">count</span> < <span style="color: navy;">20</span> )
<span style="color: maroon;">{</span>
<span style="color: green; font-style: italic;">// If we make it to 0, just spit out B's for the rest (or hot fire).</span>
<span style="color: purple;">if</span> ( <span style="font-weight: bolder;">BN_is_zero</span>(code) )
<span style="color: maroon;">{</span>
outputCode<span style="color: maroon;">[</span><span style="color: #c04000;">count</span>++<span style="color: maroon;">]</span> = <span style="color: teal;">'B'</span>;
<span style="color: purple;">continue</span>;
<span style="color: maroon;">}</span>
<span style="color: green; font-style: italic;">// Divide the code by the divisor</span>
<span style="font-weight: bolder;">BN_div</span>(result, remainder, code, rollingDivisor, ctx);
<span style="color: green; font-style: italic;">// The remainder becomes the new code</span>
<span style="font-weight: bolder;">BN_copy</span>(code, remainder);
<span style="color: green; font-style: italic;">// Adjust the divisor</span>
<span style="font-weight: bolder;">BN_div_word</span>(rollingDivisor, <span style="color: navy;">24</span>);
<span style="color: green; font-style: italic;">// Value should be in the realm of 0-23</span>
<span style="color: purple;">if</span> ( <span style="font-weight: bolder;">BN_num_bits</span>(result) > <span style="color: navy;">5</span>)
<span style="color: maroon;">{</span>
<span style="color: #c04000;">printf</span>(<span style="color: teal;">"Something is broken, too many bits\n"</span>);
<span style="color: purple;">goto</span> Exit;
<span style="color: maroon;">}</span>
<span style="color: green; font-style: italic;">// Horrible hack because BN_bn2bin didn't appear to want to work.</span>
index = <span style="font-weight: bolder;">atoi</span>(<span style="font-weight: bolder;">BN_bn2dec</span>(result));
<span style="color: green; font-style: italic;">// Save the letter of the code</span>
outputCode<span style="color: maroon;">[</span><span style="color: #c04000;">count</span>++<span style="color: maroon;">]</span> = validCharacters<span style="color: maroon;">[</span>index<span style="color: maroon;">]</span>;
<span style="color: maroon;">}</span>
</pre>
</div>
I ran it, and it worked! Some additional digging was required, as the target application also maintains an internal
blacklist of codes. I'm not sure if these are codes that they've seen shared online, or what the deal is, but there's
a list of 40-some codes. So, I added code to verify that the entered code isn't in the blacklisted code. And lastly,
the serial number that you select at generation time has to be within some defined ranges as well. So, added
some quick code to verify that, and there you have it.
An embedded Linux based internet appliance keygen.
</div>
Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-32139687332423545782015-01-16T11:27:00.000-08:002015-01-16T11:27:39.217-08:00Cross platform code sharingRecently, I've had the opportunity to examine a massively cross-platform application that's compiled for Windows, Linux, OSX, HP-UX, Solaris, AIX, etc. I've been in the software world long enough to know that companies like to write code ONCE, and then compile it on different platforms with a little platform specific "shim" code, and then ship it. It makes PERFECT sense to do this, as you can have all your bugs fixed in a shared tree, and only have to fix them once. It's even BETTER when you can leverage this work with a protection vendor who offers a protection system that runs on all your target platforms, as it allows you to write your protection code only once. <br />
<br />
But therein lies the problem. Various compilers on various OSes do things differently. For instance, the MAC compiler might leave in the debugging info and tell me that that random byte in program memory is really called "licenseObtained". And, once I know that, I can do an XREF on that memory location, and find the 2 places that it's written to. The first writes a "1" there, and exits the function, and the other writes a "0" there, and drops to a function that displays a messagebox with a message that it was "unable to obtain a license". When this happens, it doesn't matter that the compilers on the other platforms removed this label. The cat is firmly out of the bag.<br />
<br />
I heard that! You said "Big deal, you found a variable's name in one version of the application, how does that doom all the OTHER platforms?" Simple! The function that made the decision on the value to write to that memory location also read an environment variable that isn't read anywhere else in the code. So, you simply search for that string in memory, find where it's accessed, and that leads you back to the function. On ALL the platforms. Also, it helps when you don't strip your binaries, and I see that the function is named "LicenseCheck". In this case, you load the application into IDA, let it run for a while, and then tell it to GOTO "LicenseCheck", and there you are.<br />
<br />
There are a MULTITUDE of protection failures on display in this application, but the application itself is a great tool. And, I will admit that it's completely possible that the authors don't care about these failures, as protection is there solely "to keep the honest people honest". I can respect that! As someone who has seen the nastiest protection circumvented easily, it makes sense to not spend a ton of time/money trying to protect your application, as really, protection isn't your core business, and a minority of your business customers would use a pirated version, so it's not WORTH it.<br />
<br />
But, there you have it. The perils of sharing the same codebase on a multitude of platforms.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-21327038826718499362014-07-08T20:10:00.000-07:002015-01-16T11:04:51.973-08:00Mac protectionSo, I spent some time studying the facilities built into OSX that would be used by loaders, decryptors, and the like as the basis of copy protection. If you are used to protections on the PC under windows, then the Mac appears to be a dream come true for protection tourists.<br />
<br />
I decided to try to implement a simple protection of the sort I detailed in a previous post. It would be architected as follows:<br />
<br />
A simple loader application would load a 2nd application in a suspended state, locate it's initial entry point, and remove the INT 3 ($CC) instruction that I had put there. Once this was done, it would launch the app, and allow it to run. (Which would simply print "Hello World", and exit). An adequate proof of concept I thought. Since OSX is BSD based, I could just use the POSIX stuff, right? Start an app, use the apple extension to start it suspended, and then just go read/write the spawned applications memory. <br />
<br />
That's where the problems started. Evidently, there has been LOTS of activity on OSX with regards to trojans, rootkits, and the like. These have forced Apple to lock up lots of avenues into the kernel, and they've sealed off lots of tools that you would need to do good things. So, this means that most of the casual gaming protections I've seen on the Mac are shameful. As I mention elsewhere on this blog, the preferred method appears to be this: Make the loader, and license enforcer, 1 application, and it's the app that gets executed when you use the launcher. The game's main executable is renamed, and/or hidden. (Such tactics as its name starting with a ".", so that it's not shown when you ls the files in the bundle. If it's not THAT technique, then it's "rename the executable to look like a data file". Anyway, where this leads is that you 1st run the loader, and it verifies your license, and then it execs the game. No in memory patching, NOTHING. It just simply launches the game. So, to crack these games, you just delete the loader, and rename the game to match what the loader used to be called.<br />
<br />
I'll definitely be keeping my eye on Mac protections from now on, as this is somewhat fascinating to me! Stop trojans, and malware, and also stop most protection methods.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-7050710906689969462013-12-16T23:32:00.000-08:002014-07-08T20:05:07.595-07:00Learn a real language!OK, just looked at an app for a friend. It's a tool that helps fix corrupted video files. A quick glance through the files included in the archive shows that it uses MOSTLY open source utils to do the heavy lifting, while it is simply a GUI that checks the licenses, and pulls the strings. The protection on this application was a simple serial number, and without a valid number, it would only do 50% of the file. The main executable was pretty straightforward. Matter of fact, a little TOO straightforward. Ease of understanding is your enemy if you're facing me. So, watching the code, I see that they open a file with an extension of .elua. First, I thought my eyes were playing tricks on me, and it was just the EULA (End User License Agreement), which is normally a text file telling you the rights you give up by choosing to use the program. Not in this case, this was actually a .elua file. So, I see them open the file, get the file size, malloc a buffer for it, and then read it in. Then, there is a STUPID decrypt loop. I kid you not, the C code for it probably looked like this:<br />
<br />
for(x = 0; x < fileSize; x++)<br />
{<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>buffer[x] ^= 0x4F;<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>buffer[x] -= 0x16;<br />
}<br />
<div>
<br /></div>
<div>
it was simply an xor with 4F, and a subtract 16h. I guess it keeps the prying eyes out, but that's about all. They had written the code to DO this feat of software engineering in C, so they could have just as easily have used one of the REAL encryption functions from openssl or something. Anyway, it gets worse. What this file is, is the code for the GUI, in LUA! Yes, I know some video games do some things in LUA, but if you can write the C code to decrypt your file, and call the LUA interpreter to handle it, you should be able to spend the 20 minutes it would take to learn how to do the rest of the GUI in C++ under MFC. It's not the most involved GUI in the world. It's really rather simple. Since this company is still in business I can't point you to the program, or their site, but trust me. The main app has about 6 buttons on it, and none of them does anything involved. So, back to the story. We now know what's going on, so I whip up a quick application to read their file, and spit out an unencrypted version of it for my perusal. And it has the string table, and fun things like that. A function that gets info about your machine for pseudo-finger printing so that they can *in theory* lock the application to your computer. Function to check to see if you have a license file, to read it in. To check that your serial number in the license file is valid, etc. All the things that you would expect. So, I look at their code to handle the license file. Here are the steps:<br />
<br />
open file<br />
read in file, up to 100 bytes!</div>
<div>
grab the 1st 4 bytes. (Yes, only 4).</div>
<div>
Build a string from the last 4 digits of your fingerprint code. (9 - digit 3) (9 - digit 1) (9 - digit 4) (9 - digit 2)</div>
<div>
Compare this generated code to the code that you entered. Oh also compare it to the fixed value 4475.</div>
<div>
If either of these matches, LICENSE IS GOOD! FULL VERSION!</div>
<div>
<br /></div>
<div>
*FACEPALM* They had a reasonable idea going along, and then 4 digits? Seriously? Backdoor code left in by the developer? WHY? And in LUA, where any jackleg can come along, decrypt the file, and see your original source. Just pathetic!<br />
<br />
****UPDATE****<br />
<br />
I did a little more digging, and the situation gets a little MORE pathetic. I thought about this, and considered "Maybe they know nothing about C, and this was their only way to make a product! They found some code online that let them embedded a LUA VM, and launch their code, and the load/decrypt was all that they could muster." In which case, I can kinda understand their suckage. Not so kemosabe. As they like to say in the NFL, "Upon further review". I spent a few minutes digging into the application that launches their script. It's not JUST a launcher! It contains a library of functions in a custom namespace that they call from inside their LUA script. What really triggered this, is I was curious to find out how their "Machine ID" function worked. So, they have the chops to develop an entire library of utility functions in C, on windows AND Mac! Yet they can't be bothered to develop a GUI in something other than LUA. And, as I typed that last sentence, it hit me. This is the worlds lamest cross-platform application. Develop the GUI once in LUA, write stock C code, compile it on windows, and mac, and ship it. OK, well, moving on. So where DOES this vaunted Machine ID come from? Why from here: "SELECT ReleaseDate FROM Win32_BIOS" I should check the Mac version, since this facility isn't available on the Mac. Stay tuned. This could be epic!</div>
Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com1tag:blogger.com,1999:blog-8372391096309720317.post-80746339944193417822012-11-18T19:57:00.001-08:002012-11-20T17:55:11.295-08:00Casual Gaming ProtectionsOver the years, I've been fortunate to see lots of protections on so called "Casual Gaming" games. These are the games like Bejeweled, and that ilk. Generally, these games are written by a company, and provided to several online "publishers", who distribute them. Reflexive.com, Yahoo Games, people like that.<br />
<br />
Well, the games are provided in their original unprotected "ready to run" form, and the individual publishers add their own protection to them to enforce their "60 minute free trial" restrictions. The quality of this publisher applied protection varies wildly. I will touch on some of the ones that I have seen in this posting.
<br />
<br />
Generally speaking, there are 2 types of protections in use. The first one is where the publisher uses some "off the shelf" protection to either manage the entirety of the trial, or at least in an attempt to thwart circumvention of their trial system. These are things like the Armadillo protection system from Silicon Realms, and systems of that type. Generally, these are more successful than if the publisher had written the whole thing from scratch, as more than likely, the game author isn't going to be an authority on copy protection, and that job should be left to the professionals (As you'll see in the OTHER category a little later). The problem with these "solutions" is that MANY MANY tools exist online for removing, stripping, or at least circumventing them. As mentioned elsewhere on this blog, that is one of the perils of off the shelf protection.
<br />
<br />
This class also includes more of a hybrid system, where the company develops a protection on their own, and uses the packer/protector over the top to at least act as a speed bump (sleeping policeman if you will) to the would be hackers. But these suffer the same fate as the full blown systems mentioned previously. These packers run the gamut from the fully commercial ASProtect, down to the lowly open source UPX. And, ultimately, if you are counting on a packer to protect you, you truly have no protection at all.
<br />
<br />
The other type, is the entirely self written protection system. These are the ones that I'll be spending the most time talking about in this post, as to me, they're the most hilarious. I'm not trying to pan ALL of them, as I've seen some that weren't bad! I saw one that did 2 asm instructions, and a jmp, over and over and over. Very reminiscent of the old floppy based protection called SuperLock. (I have a copy of that around here somewhere). It also goes through a couple of layers of decryption, and unpacking, and runs code from inside itself, so it plugs the obvious "memory dump" holes. Honestly, I forget who had this protection, but it was pretty good. Now, with that one out of the way, we can move on to the others.
<br />
<br />
There are a couple of publishers who share the idea that renaming the .exe to something else, and setting the "hidden" attribute on the file is enough to stop piracy. I kid you not! When you install the game, they install everything, and create a shortcut on the desktop. This shortcut leads to their monolithic loader that keeps track of your time playing, and how much time you have left, etc. It also has intrinsic ads, and serves as your gateway to download more of their games. It also features code that loads, and runs the game from it's super secret location. (The root of the game install directory). The solution to this protection is ALMOST as bad as Popeye mentioned in previous posts, and just barely better than Superman also mentioned elsewhere. So, the method to "crack" these games, is to rename the .exe back to .exe, and update the shortcut's target. TA DA! (Shaking head).
<br />
<br />
We've now covered the good, and the bad, which brings us to the most popular technique. This one utilizes a technique where the code at the initial entry point is removed/encrypted/scrambled in the game, and the loader/time tracker replaces it at runtime. It creates the task suspended, and then through WriteProcessMemory they replace the garbage at the OEP with the correct (original) code, and then perform a ResumeThread to launch the game. This was a pretty cool idea back in 2004 when I first saw it, but this is 2012, and it seems to be becoming MORE popular, not less. I've found derivatives of this idea in *3* different companies protection schemes. And NO, packing you loader with ASProtect doesn't help. It also doesn't help if your ASProtected loader loads an ASProtected .dll to do all the work. It all results in the same thing. An API hook eats your lunch, and allows someone to dump out the data, or in some cases, (like mine), I copy your "altered" game to a new name, and replace the correct bytes "on the fly" as the loader runs.
<br />
<br />
The only thing worse than these windows protections, are their Mac counterparts. Say you have a game called "Fool's Errand". You have a bundle that holds all the files, and it contains the loader, named "Fool's Errand", and all the support files. Among these is a copy of the REAL executable, UNTOUCHED. Just renamed to something that's supposed to blend in with the other files. The downfall of all of these is when you launch the game, and from a terminal do a simple "ps x", and see 2 things running. 1 the loader "Fool's Errand", and something else, from the same bundle, called "data". Once you see that, you exit the game, delete the loader, rename data to Fool's Errand, and play forever. Just simply pathetic!Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com1tag:blogger.com,1999:blog-8372391096309720317.post-50899589933810269742012-08-26T21:59:00.001-07:002012-10-06T20:55:24.681-07:00I saw a well designed protection!I know that normally in this space I rant about how bad this protection was, or how pathetic THAT protection was. But this post will be different. I recently had the opportunity to see an amazingly well designed protection system. Strangest of all, it was a homegrown protection written by what looks like a small developer.
No, I don't know the name of the protection, and I won't tell you what packages it was on, but I'll tell you ABOUT it.
The packages are both from the same source, a presumably small independent developer who produced a package to aid in the generation, and distribution of test taking tutors. Say you want to get you Linux+ certification, you can go to the web, and buy their package, and it'll help you study for the test.
The target installs, and presents you with a single .exe. A quick scan tells you that it's an encapsulated Java application, with an executable launcher. A quick search, and you can pull out the whole jar file that is the program, and a quick unzip later, and you have all the .class files. Run them through decompiler of your choice, and you'll soon see that they've been obfuscated. While the obfuscated code is difficult to follow, the error messages that the application prints leads you to the right place in record time. You can see that a particular function gets called, and it's return value means the code you entered is bad, or that you're running in demo mode, or that your trial has expired.
So, now a quick note. I've never learned Java. C/C++, yes, Java? No. So, that means that I have to consult the web for parameters to APIs, or what a particular API itself does. So, I see the application getting a resource, and using it in what looks like a way that would tell me EVERYTHING. So, I google the string. And what I find, is absolutely shocking. I find the COMPLETE source to the package. ALL OF IT. For whatever reason, the developer at this company kept his Eclipse workspace on the web server machine. A quick "wget", and I had the complete source, with comments, and even notes to their customers describing how their protection works. Game over, right?
NO. And here's why. The protection is well designed. When you hit their website, if you opt for the demo, you get that. A demo package, with only 10 questions. (Out of who knows HOW many for the regular package). If you don't BUY a test, you can't get the executable, and all the questions. That's good idea number 1. If a pirate can't TOUCH your app., he can't crack/pirate it. Number 2. Once you get the package, you also get a serial number. When you run the app., the first thing you are presented with, is a registration box asking for that serial number that you were given. It takes this, and grabs some stats like your MB serial number, your MAC address, etc., and interlaces all this data into a packet that it sends to their registration server. The registration server returns the time period that your application is authorized for, and, (Drumroll please), the AES key to decrypt the questions database. This data is all interlaced together, and BASE64'd for the trip. The client application pulls the packet apart, save the dates, and the key for the questions, and boom. Off you go.
Now, as a pirate, I'm all about weaknesses in the system. YES, you could prolong the license period forever. YES, you could buy all the tests once, and pull the private key out, and release them at once. (That would probably be kinda obvious though).
As part of the glob that I downloaded, there were all the tools to be used by the customers to enter test questions into the questions database, and, the private keys for a bunch that already exist. So, in THEORY, if you could get all the applications, you could release them all without having to BUY them. But, this takes us back to problem #1. You don't get the application if you don't BUY it first.
So, on a tour de force level, this protection scheme is relatively low tech, but it is above all, EFFECTIVE.
So, good job who ever you are that wrote it!Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-10810721578285539772012-03-27T21:32:00.002-07:002012-03-27T21:44:46.156-07:00Sometimes I think you should have to have a license to write protection.Tonight's application was a database monitoring application written mostly in unobfuscated java. Is this 1999 and no one told me? I mean SERIOUSLY. And the thing that made it all that much better was that this code runs under Tomcat, and while running something called Jasper, it spit out .java versions of some of the important files. I didn't even have to decompile them! (shaking head). OK, so here's how it all works. You get a license key from the vendor when you register your trial, or buy a license from them. It comes in the form of a string of characters that you copy & paste into a form in the program. (It's all web based evidently). This license key contains a server name if you buy a license, or a string that they identify later as the "trial sentinel", and a number. This number is the time since the epoch in milliseconds for when your trial, or license expires. At runtime, in just about every module, they load this string from the key file, decrypt it, and pull the 2 halves out. (There is a delineation character between the fields). Then, they simply compare the time to now, if it comes back negative, your license has expired, and you need to get a new one. <br /><br />So, as you see, the lynch pin of this WHOLE protection boils down to a simple string decryption routine. It was written in java as well, and unobfuscated for your reversing pleasure. A little while examining it, and I was able to write my very own ENcrypter, so that I can now make license files till the cows come home. Here's the pertinent code:<br /><br /><br />void EncryptString(char *s)<br />{<br /> char temp[1026];<br /> char output[2049];<br /> unsigned char x, y;<br /> unsigned char len = (strlen(s) & 0xFF);<br /><br /> memset(temp, 0x00, 1026);<br /> memset(output, 0x00, 2049);<br /><br /> temp[0] = len ^ 0x95;<br /> temp[1] = s[0] ^ 0x95;<br /> temp[2] = s[1] ^ 0x59;<br /> <br /> for(x = 3; x <= len; x++)<br /> {<br /> temp[x] = s[x - 1] ^ temp[x - 3];<br /> }<br /><br /> for(x = 0, y = 0; x <= len; x++)<br /> {<br /> output[y++] = ((temp[x] & 0xF0) >> 4) | 0x40;<br /> output[y++] = (temp[x] & 0x0F) | 0x40;<br /> }<br /><br /> printf("[%s]\n", output);<br />}<br /><br />The 1st byte of the license is the LENGTH xor'd with 0x95, followed by the serverID, followed by the expiration time. They do a pseudo rolling encryption where the value of THIS byte is xor'd with the value of another byte in the string, (3 bytes away). Once they have this, they simply walk through the string, pull out the upper nibble, shift it right, and OR it with 0x40, as that makes it printable, and then pull the lower nibble, and OR it with 0x40. Then, save those bytes, and move along. So, the resulting string ends up being twice as long as the actual payload.<br /><br />I can only hope that these guys kick ass on database applications, and that it works better than their attempt at protection. Maybe they're finally wising up, and are only trying to "keep the honest people honest", as that's about all this scheme would do.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-51013303572289468282011-09-11T20:42:00.000-07:002011-09-11T21:01:46.675-07:00Linux "Driverless dongles"Recently, I've had the pleasure to examine the libraries, and implementation code associated with the new generation of "driverless dongles" under Linux. I've examined two different products from different companies, both with the same "feature" on their keys. This feature is the ability to plug it into the box, and not have it require a driver be loaded for your application to work. To facilitate this feat, they simple assign their dongle to the HID (Human Interface Device) class in their USB descriptors, and when it's plugged in, Linux enumerates it, adds it to the tree, and that's that. Then, when the time comes to talk to it from a protected application, you use a library provided by the publisher. It has mostly been this library that has allowed me to gain a full understanding of a key that I've never touched, and another that I have. It seems that both companies, NOT related, and THOUSANDS of miles apart, had the same idea. "Let's use libusb inside our library, so that the code will be simple!". Well, that it is. A little TOO simple. After finding the library online, and tossing it into IDA Pro, I was able to determine that it was libusb, determine the version, and then see how they used it. Now, for your protection to be simple enough that a guy like me can spend about 30 minutes with it, and have a complete grasp of it, is kinda sad. <br /><br />The pitfalls that I saw included the following:<br /><br />* Forgetting(?) to strip the symbols from the library before shipping. This allows IDA to label all the functions and makes the whole process MUCH simpler to understand.<br /><br />* Publishing the entire API spec, and library to the net, so that ANYONE can get a copy of it. I understand that it's a delicate issue of "We want developers to be able to look at how easy it all it". But, you're also giving away the keys to the store at the same time. As this also allowed someone to see where this library is integrated into a customer's program, and have a COMPLETE understanding of the names of the functions, as well as what they do.<br /><br />* Using libusb. I understand that you want the library to be as simple, yet robust as possible, and that using an available, and THOROUGHLY tested lib makes that process much easier, but it also makes the reverse engineering process much easier as well.<br /><br />I heard you saying "Those are all interesting things, but what do these holes allow me to do?". Well, here's what I was able to do. I developed a driver that registered itself with the USB stack as a dongle. Then, when the applications enumerated the devices, they found ME, assumed I was a key, and began talking to me. A VERY little debugging of the target application, and I was able to return the "right" answers to the applications challenges. <br /><br />Once I acquired my own key of the 2nd type, I was able to write a VERY SMALL driver (400 lines of C code!), that was able to intercept all communications with the dongle, and "change" the data that my dongle was returning that wouldn't match what the application was expecting. (Login passwords that the dongle requires, GUIDs, etc.) So, now, the target application runs with a key that isn't the right one. It even reads the memory from the key, and everything else that it's supposed to do, and has no idea that I'm there.<br /><br />I could write a BOOK on how bad the code was in the target application, but even had that NOT been the case, this still would have been an easy crack job.<br /><br />If you are just starting Linux reverse engineering, and are faced with a dongle, I *HIGHLY* recommend that you look into an option called "usbfs_snoop". You can find it under the /proc tree. This will show you what types of IOCTLs are being sent to the key. Pair that up with strace, and you have a potent 1-2 punch.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com1tag:blogger.com,1999:blog-8372391096309720317.post-55078588681619799502011-05-20T20:46:00.000-07:002011-06-08T14:32:32.260-07:00Great moments in protection failure!It seems that more and more these days I find protection to talk about here only because of the epic badness of it. I'm sure there's some good out there, but I haven't seen any of it lately. Anyway, on with today's installment of "Great moments in protection failure!"<br /><br />Looking through an anonymous application that does a whole boat load of decryption of data from a source. The main application was compiled, and released with the symbols still in it, so IDA gives me not only function names, but function prototypes, and in a few places, variable names. You know, this could be a simple mistake, and crap happens, so I'll cut them some slack on this, as this isn't even the failure in question.<br /><br />While digging through the application and analyzing the encryption bits (the only things really interesting in there to be honest), I find that the guts of the encryption routines have been pseudo-obfuscated. I'm assuming that this code is from a library that probably came this way from the original manufacturer. By the looks of it, it's some tool that they run after they compile the library, and it changes all the non-exported function names in the library to a long string of hex characters. For example, they might have a function named "000b00f05c86d185". So, when you're looking at the disassembly, you see:<br /><br />call _00b00f05c86d185<br /><br />This is fine, and a good idea if you're trying to hide what your functions do, but now to the facepalm moment.<br /><br />In this code, they call the obfuscated functions, and if they return an error value, they print a nice debug string that contains all the details about the error. Including the original name of the function!<br /><br />So, all their attempted obfuscation is undermined by their proficient use of error messages.<br /><br />Let's use our example function from above. You'd see something like this (in C pseudo-code).<br /><br />if(00b00f05c86d185() != 1)<br />{<br /> printf("GetKeyValue() returned error\n");<br /> return 1;<br />}<br /><br />Gee. I wonder what the REAL name of "00b00f05c86d185" is?Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-5943701781251375942011-03-21T13:02:00.001-07:002011-03-21T13:11:23.592-07:00*FACEPALM*This was just too good to not share. <div><br /></div><div>Just had a look at an app for a friend that used a dongle. (Some weird brand/model of dongle that I'd never heard of before). So, I run the normal analysis on the application, and see that the author has chosen to pack his executable. Not a bad idea! If you want to do this for the protection/anti-tamper benefits of a compressed application, I would HIGHLY recommend not using an open source, and publicly available compressor. In this case, it was UPX. (<a href="http://upx.sourceforge.net/">http://upx.sourceforge.net/</a>)</div><div><br /></div><div>A quick look around the net, and I had an app that not only could tell you ALL about the compression on the app, but also removed it, cleaned up the .exe and everything else. Spit out a virgin looking executable. </div><div><br /></div><div>So, on to the next step. Load it into IDA, and have a look around. I quickly find the "USB Dongle not found" string, and trace that back to a function that does a couple of things (calls ebp+xxx based functions), and makes a decision about the results. A little digging revealed that they were dynamically loading a DLL from inside themselves, (Almost like a resource), and then doing a loop of "GetProcAddress" to get the addresses of the functions they wanted. Each was stored in an ebp+xxx location. Turns out that he only called the dongle function from 2 places, once on startup, and then he spawned a thread that checked that the dongle was STILL attached every 3 seconds. Not bad dude, not bad at all.</div><div><br /></div><div>Then, while looking at the functions that called the dongle function, I noticed a comparison of ebp+644, and if this value was 0, it skipped not only the startup check, but didn't create the thread to continuously check the key either. What's going on here?</div><div><br /></div><div>It was ... A command line option to skip the protection completely. When the program started, one of the first things that he did was to get the command line, and to use strstr to search for his magic string. If found, it would clear the flag, and the protection routines never got executed.<br /></div><div><br />FAIL!<br /></div>Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com1tag:blogger.com,1999:blog-8372391096309720317.post-77094309554333039622011-03-01T09:59:00.000-08:002011-03-01T10:19:15.606-08:00The perils of commercial protectionI just finished up looking at a commercial package that runs on Linux, and uses a SmartKey dongle from some guys in Italy. The dongle design looks as good as any other, and as Rainbow used to advertise a long time ago, "people never attack the key". This was true in this case as well. There were 4 or 5 apps in the package that were protected. (They basically just read memory locations from the key to see if the options pertinent to their situation were enabled or not). For instance, the report generation module would check the key to see if the memory location set aside for it had the correct value in it, or not, and used this value to determine whether to generate the reports, or, I don't know, put a "this is a demo version" banner on them or something. Anyway, you get the idea. <br /><br />Now, on to the perils of commercial protection. Specifically "off the shelf protection". The programmer who wrote the apps seemed like he knew how to write apps, but not really design a good protection system. And it's this scenario that exposes the peril most directly. As I said above, there were 4 or 5 apps that were protected. He wrote them in C, and linked against the library provided by the dongle manufacturer to implement his checks. The big problem here, is that you now have a big glob of code in each of your protected executables that's not only the SAME in every app, but is the heart of your protection system. In a posting prior to this one, I detail how I gutted and "repurposed" a function in the Sentinel .DLL in an app called SNMPc. This would certainly be possible with these apps as well, but instead of gutting a common library, you'd be doing a simple search and replace of some code in each executable. In this particular case, the library contained an error message that would print if something happened to cause the communications with the key to get out of sync. So, the procedure for each app was:<br /><br />Run through IDA<br />Search for string<br />Trace backwards to find caller(s)<br /><br />Using this technique, I was able to completely understand what data the dongle contained, and how each byte was used in each program. So, instead of providing the protection that the author expected, it actually made his apps EASIER to crack.<br /><br />In the span of a couple of hours, I was able to rewrite the "checker program" that the client app used to verify your permissions in C, and have it work flawlessly. All with information that I had garnered thanks to the staticly linked routines in his apps.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-81634799720249231732010-06-09T15:54:00.001-07:002010-06-09T16:01:33.167-07:00Another thing to NOT do.I just examined a protection system for folks who write apps in the Borland languages, and want to distribute demo versions. It's the "R & T Software Registration Control". I normally don't tell names of protection systems, but since their website is down, I assume they're out of business, and fair game.<div><br /></div><div>The app that I was examining called 2 methods from their control. The first was to get the days remaining in the trial, and the 2nd was to get the "level" of your license key. (Evidently you can generate keys that are capable of enabling multiple items in an app.) The 1st function returned the number of days left in AX. Well, they populate AX with some huge number prior to the call, so the fix for that was to change the 1st byte of the function to a RETN. Now, when it returns, it checks the number of days left on the trial, and it's some astronomical number, and it doesn't bother to nag you about registering, and most importantly doesn't exit.</div><div><br /></div><div>The 2nd call returned a value that was immediately and'ed with 3. (Evidently only 3 levels in this app.) Well, as fate would have it, they also passed in a huge value that had the lower 2 bits set, so I changed the 1st byte of that function to a RETN as well. It returned, and'ed off the rest of the bits, saw the 3, and said "Full access!". </div><div><br /></div><div>Obviously this was more the fault of the main app itself, but it's completely possible that this control required those crazy values to be passed in in AX, and if that's the case, they were completely self defeating. I neutered their entire $99 protection system with a 2 byte change.</div>Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-59067134466680198432010-05-25T19:35:00.000-07:002010-06-09T15:54:02.152-07:00Fab tackles a Mac program.While not technically my FIRST Mac app, this was an interesting diversion if nothing else. The first app was a Mac port of a protection system that I had conquered on the windows side YEARS before, and I knew it intimately. SO that didn't really count. Some of my friends used this app at the office, but would like to have a copy at home so as to become more proficient with it. So, out of sheer boredom, I decided to have a look at it. What I found excited me. If ALL Mac apps are this easy, I might have to start taking requests!<div><br /></div><div>First a few notes about Mac apps in general. Most of the more modern apps are compiled for both x86 and PPC chips, and the resultant output files are stuffed into a single file together for distribution. So, I did both versions. Now, not being a PPC hacker, that took a few minutes, but the mistakes that they made in the x86 version were also present in the PPC version, so it was a lot easier than it should have been. </div><div><br /></div><div>In this particular case, (and I hope all others!), the way that the Mac compiler generates executables, and probably the whole underlying architecture of OSX makes reversing MUCH simpler. It's almost like there's an API for everything! To wit, this code looks odd enough, nothing really to see here, right?</div><div><br /></div><div><div>__text:000DB4CB mov eax, ds:off_1D2514</div><div>__text:000DB4D0 mov [esp], eax</div><div>__text:000DB4D3 call _objc_msgSend</div><div><br /></div><div>If you checkout off_1D2514, you discover that it's a pointer to NSConditionLock. So, spend a few minutes labeling all these "pointers to message names", and the disassembly starts to look VERY different!</div><div><br /></div><div>Of course, if the particular program that you're working on uses a license file protection technique, and offers a demo version, then it could be even easier. It could have a function like this:</div></div><div><div>char __cdecl _XXApplication_isDemo_()</div><div>{</div><div> return *pTrialByte == 3;</div><div>}</div><div><br /></div><div>Variable name was supplied by me, function name was left in the executable by them. Don't get me wrong, I certainly APPRECIATE it! ;-)</div><div><br /></div><div>So with this function telling me not only what variable in memory was responsible for determining the trial/registered status of the app, but also what the value was that was interpreted as being a trial, it allowed me to make a simple fix. Just locate all the places in memory where this memory location was set. I.E. </div><div><br /></div><div>__text:000E0453 mov ds:TrialByte, 3</div><div><br /></div><div>A little more tracing showed me that a value of "1" in TrialByte meant that the app was registered, and happy. So a simple search revealed 3 places where a value other than "1" was being placed in this location. A simple change of "2" to "1", and a couple of "3" to "1" changes, and we were done. </div><div><br /></div><div>I heard that! You said "What about the PPC version?". Well, I found much the same code there:</div><div><br /></div><div><div>__text:0000B470 __XXApplication_isDemo_:</div><div>__text:0000B470 lis %rtoc, ((pTrialByte+0x10000)@h)</div><div>__text:0000B474 lwz %rtoc, pTrialByte@l(%rtoc)</div><div>__text:0000B478 lwz %r3, 0(%rtoc)</div><div>__text:0000B47C xori %r3, %r3, 3</div><div>__text:0000B480 subfic %r0, %r3, 0</div><div>__text:0000B484 adde %r3, %r0, %r3</div><div>__text:0000B488 blr</div><div>__text:0000B488 # End of function __XXApplication_isDemo_</div><div><br /></div><div>This is our handy function for locating the variable, and what do you know? A quick search shows that there are 3 places that need to be patched to make it work. The same as the x86 version.</div></div></div>Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com1tag:blogger.com,1999:blog-8372391096309720317.post-5332462924368410292009-10-31T21:42:00.000-07:002009-10-31T21:48:49.029-07:0025th Anniversary of cracking/ReversingThis very night, 25 years ago, I became "Fabulous Furlough". <div><br /></div><div>I was hacking on a C-64 game in my best friend's basement at 2425 Vale Lane in Nashville on that faithful night. I don't recall where we GOT this game, but I do remember that it had several "Error 23" checks on the disk, and I fixed the first bunch, and we tried to load it, and it failed. So, I had to go search for another one. Found it, and the crack was done, then came the "putting my name on the loading screen" part. I found this nice line near the top of the loading screen, and counted the characters that were available there. 27. Prior to this game, I had just been "Chris from The Dream Team". (No, not THAT dream team, the name came from the fact that my friend was a good hardware hacker, and when you put us together, we were in essence, a "dream team".)</div><div>So, I needed a new name. I worked out that "Broken by" was 9 characters, and needed something to call myself. I have no idea where the inspiration for Fabulous Furlough came from. It just popped into my head, I counted up the characters, and it fit. I laughed, and loaded up the sector editor, and did it. </div><div><br /></div><div>Then loaded the game to make sure it still worked, it did, and from that point on, I was Fabulous Furlough.</div><div><br /></div><div>And here we are, 25 years later.</div><div><br /></div><div>Special thanks to the late Mike Jackson (MTJ!). Without you, I would never have learned this great skill. May you rest in peace buddy, I'll always miss you.</div><div><br /></div><div>-FF</div><div><br /></div>Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-73493553821120577192009-08-01T19:34:00.001-07:002009-08-01T19:39:22.618-07:00What good does that do me?This is kind of a follow up for the next story down. So, I wrote the tool to grab the unprotected game executable, and make a new package with it. It worked, I was happy! I sent it to my friend with the Mac, and he reports back that it won't run. After a few iterations via e-mail, he tells me that he has an older PPC MacBook. I wrote this code on an Intel based Hackintosh. (Dell D610 that runs MacOS 10.5). So, my options were to recompile it for PPC, make a FAT executable that houses BOTH executable formats, or something else. I of course opted for option C. In this case, that turned out to be "Write the fixer app in PERL". PERL has been my hobby language for a LONG time, so I figured I'd give it a shot, and see what I could do. Basically, I took the C code functions, and rewrote each of them in PERL, and then just called them in the correct order. Works like a charm! I think this is my first "cross-platform" crack.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-19911047948856616722009-06-18T19:51:00.000-07:002009-06-18T20:21:03.904-07:00That's not my platform!Recently I've been stalking this company that distributes games written by 3rd parties. I won't mention their name because I'm having too much fun with them! ;-)<div><br /></div><div>So here's how it all began. My wife plays a lot of PC based puzzle games. Some people work crossword puzzles, some others crack software, she plays puzzle games. So, back in 2005 she found a game that she liked called Mystery case files huntsville. She downloaded it, and asked me to extend her trial time. So, I went looking for a crack. (Why reinvent the wheel if it's already been done?) And I found one. So, I tried it, and it didn't work. Well, that pissed me off, and I decided to have a look at it. I ran it through IDA (my disassembler of choice), and began looking at the code. It was pretty straightforward, they loaded the game into memory without executing it, read a chunk out, decrypted it, wrote it back, and the executed the game. I then looked a little further, and found where they checked to see if you had purchased the game. I kid you not, the function was called "HasProductBeenPurchased", and returned TRUE or FALSE. Basically YES or NO. This was in a .DLL, so I made the simple change to make it always return TRUE (yes). Ran the game, nothing. Exited. I dug through their loader a little more, and found that they were doing an MD5 over the DLL to keep people like me from doing what I was trying to do. The only problem is, the loader itself didn't have any such protection, so I just made it jump like it had received a TRUE retun value, and she was playing along happily, but I was now intrigued! SURELY this was just a single instance of bad protection! I went back to their site, and saw that they had about 100 games available for download. I grabbed a couple, installed them, and looked at the loaders. The loaders were almost all the same! It turns out that this weak protection was on ALMOST ALL of their games. The only exceptions were what was probably the FIRST games they released, and they didn't have the loader system perfected yet, so they just had the game authors call "HasProductBeenPurchased" from inside the game's executable, and then they packed it with a packer called ASProtect. I decided that I was going to write a tool to let my wife register her own games when she wanted to. So, I wrote a loader that allowed me to get around the ASProtect games, and a patcher that allowed me to patch the OTHER games, and a stripper that removed their protection completely. </div><div><br /></div><div><br /></div><div>Seems like this would be a good time to explain the process that they use. When an author gives them a game to distribute, they take the executable and run their packager on it. It reads a chunk of the games executable code out, encrypts it, writes it back, and then renames the executable from .exe to .rwg. (I bet it's the authors initials!). They then throw a loader on that does stuff like allow you to purchase the game, it monitors how long you've played, and doesn't allow you to play after your "trial time" has expired. (It will kill the game, and return you to it when your time is up!). They then pack the whole thing up with an installer, and put it on their website. This protection method means that when you press the "play game" button in their loader, that they have to decrypt that chunk of data in memory, and then launch the game from there. What my loader did was, search for, and replace some strategic bytes in their loader with "$CC" bytes (INT 3) bytes which transferred control back to MY program, and I would read the decrypted data out, and make a patch for the game. It was very "old school" if you will, what with all the searching for bytes, and whatnot. They accomplished this reading and writing of memory via a couple of windows functions called ReadProcessMemory, and WriteProcessMemory. They do just what you would think they would. They allow one process to read/write in another processes memory space. </div><div><br /></div><div>Well, I decided to update my tool, and bring it to the jet age. I used a technique called "IAT Hooking". What this is, is when their loader loads, they load the windows DLLs that house the Read/Write ProcessMemory functions. When they do this, I intercept them, and instead of them getting the addresses of the windows functions, they get the addresses of my "replacement functions". In these functions, I do things like copy the encrypted executable to a new name, find the location where the encrypted code is in that file, and write the unencrypted code out to that location when they get through unencrypting it. And, the best part, It works on every game they have released since 2005! I bet that's close to, if not over 1000 games!</div><div><br /></div><div>I was very happy with this tool, and figured that I had exploited them as much as I possibly could. I was wrong. Recently I noticed that their site had added a Macintosh section. And, with Macs being Intel based these days, I figured I'd have a look at their loader on that platform, and see if they were doing the same thing. They are, sorta. Only with 50% more braindead free!</div><div><br /></div><div>The packaging step is the same, read a chunk of the executable out, encrypt it, and write it back. But the loading/running of the game is different, and COMPLETELY STUPID. Instead of loading the game into memory, and making those changes I mentioned above, they actually make a copy of the encrypted executable, read the encrypted data from it, decrypt it, write it back, and then execute it. So, when the game is running, there is a completely UNPROTECTED copy of the executable on your HDD just WAITING for you to make a copy! They rename it slightly, by adding a "." to the front, but very little good THAT does! So, I'm going to write a tool that will find, and copy the unprotected executable to a safe location, and then when the game exits, I'll delete the encrypted version, AND the loader, and put the good version of the game in it's place. Reducing the size of the bundle on your HDD, and letting you play the game forever.</div><div><br /></div><div>(shaking head)</div><div><br /></div><div>Idiots.</div><div><br /></div>Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-74728607830983008842008-09-13T22:27:00.000-07:002009-01-30T11:02:13.460-08:00Some more things that occured to me. While working for a gaming company, I was asked to have a look at an FPGA design program from Xilinx. We owned it and all, but they wanted to not have to use the dongle. I didn't care the reason. Anyway, when you ran the program, it checked to see that the dongle was there, and if it wasn't it just exited. If it WAS there, it ran. And never checked it again unless you stopped the program and started it over. Really, what was the reason for this? It was almost like the protection was an afterthought, or demanded by management.<div><br /></div><div>I also did an app called SNMPc. It had the typical run of the mill Sentinel Pro dongle. Back in the "old days" the way the dongle worked was this: You sent it a string (usually a short one), and it sent you back a 16-bit number. So, SNMPc sent a bunch of strings that were lyrics from Pink Floyd's "Shine on you crazy diamond". It looked like they used a library for calling the dongle functions, as all the code looked the same. The way the dongle code existed, was in a .DLL. Which makes sense, you can distribute it with any app, and not have to change it if you are the Rainbow (The dongle) people. The problem with that, is that once you have cracked it, you know where everything is inside it, and the next crack is trivial to do. The way that I did this one, was to look for the places that called the dongle check routine. (The bytes were the same, so a simple hex search turned them all up). Then, I looked at what the string was that they were sending to the dongle, and at the compare right after the call to see what they expected to get back, and made a table. Then, I went into the .DLL, and gutted the dongle check function. I replaced it with a look-up function that I wrote that compared the sent string to the strings in my table, when it found a match, it returned the corresponding 16-bit value. DONE!</div><div><br /></div><div>Sometime, when Google feels like it, if you search for my name "Fabulous Furlough", you'll find a text file "interview" written by some idiot from 1993 or so. In this file, the interviewer is asking some guy with Razor about the best crackers on the PC. (in that era). He says that he wouldn't put me in the top 10 because I never did an interpreter, and I never cracked dongles. I'd like to take a little space to clear both of these misconceptions up.</div><div><br /></div><div>Ultima 6 was an interpreter, and I cracked it without help. (It took 8 hours, but I did it). I have also cracked VB apps, which are interpreted, and Deadbolt 64 (mentioned elsewhere on this blog). (And probably a bunch of other stuff that currently slips my mind). Now, on to the issue with dongles. During the timeframe in question, what this idiot didn't know was that I was the "secret cracker" for a group called NTA. (Nocturnal Trading Alliance) out of Phoenix. Mikeysoft was the head. They didn't have a cracker, and since THG wasn't interested in doing business apps officially*, we left them to Mikey. So, during the timeframe that he speaks of, I cracked NUMEROUS copies of 3D Studio, and a bunch of other business apps that were dongled. So, the Razor guy was a know-nothing idiot who was just shooting his mouth off. </div><div><br /></div><div>UPDATE: TODAY Goggle felt like giving me the link to the idiot's post. So, here you go:</div><div><br /></div><div><a href="http://web.textfiles.com/ezines/NAKEDTRUTH/ntm-05.txt">http://web.textfiles.com/ezines/NAKEDTRUTH/ntm-05.txt</a><br /></div><div><br /></div><div>*The reason we weren't interested in business apps was this: We assumed that if a company lost sales of 1000 copies of a game at $30 each, it wasn't worth the time and hassle to come and find us. But, on the other hand, if a company lost sales of 1000 copies of a $10,000 program, THEN you have a reason to hunt people down. (I once downloaded a financial analysis app worth $750K. No shit.) Wasn't protected, and came on one (1) 720K floppy. I have NO idea what it did, but it better have shit gold bars, and farted rainbows for that kind of money.</div>Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0tag:blogger.com,1999:blog-8372391096309720317.post-49946582776894367182008-08-11T22:37:00.000-07:002008-08-11T22:47:01.091-07:00Some quick hits.I also cracked games on the Amiga. It being 68000 based, it was a whole new game for me. (Pardon the pun there).<br /><br />I cracked a bunch of things, but the first was "Empire: War game of the century", and that was only fitting, as it was also the first PC game that I ever cracked. (Using Microsoft's CodeView, and Norton Utilities of all things). But the one game that I really remember was a game called Foundation's Waste. I couldn't tell you what kind of game it was, what the object of the game was or anything, but here is the stuff that I CAN tell you. It had a nasty protection that none of the copiers would copy. I tried everything in my arsenal, and couldn't get a working copy. Best of all, when your copy didn't work, it played Vincent Price's laugh from Michael Jackson's Thriller. I laughed really hard the first time it did it. This was also one of those games that was all based off of sector locations on the disk. There was no real directory, and you just booted the disk to get the game to run. So, I had a tool that would read a sector, and disassemble it. So, I started with the boot sector, went to the next sector that it chained to, and a couple of sectors later, I found the protection check, and the call to the digitzed laughter. I couldn't resist. My crack of the game came up, and played the laugh, and THEN loaded the game and let you play it. I thought it was the ultimate F*CK YOU to the authors who thought they were being cute.<br /><br />On the PC, another beauty of copy protection was a "port" of Nintendo's Popeye from the arcades. The protection was in a .com file that the included batch file ran. It checked the disk, and if the protection passed, it ran the NORMAL .exe there. Crack? Delete the .com file, and rename the .exe. DONE! A crack without modifying any code.<br /><br />There was also this game called Mean Streets by Access Software. When you ran it, it checked the key disk in text mode, and if it passed, it THEN switched to graphics mode. It was VERY easy to crack, as you could use debug, codeview, turbo debugger, almost anything, as they didn't change the video mode, which was what stopped you from using most of those tools.Fabulous Furloughhttp://www.blogger.com/profile/10505264425065093824noreply@blogger.com0