AdwareAlert, would pose as a cybersecurity hero but plays the role of a digital scam artist. Users, often anticipating the protection of Lavasoft’s Ad-Aware, would fall victim to AdwareAlert’s deceptive tactics, including fake scans and demands for payment to fix nonexistent issues. AdwareAlert would don the hero’s mask but wound up as the unsuspected villain of digital deception.
AdwareAlert is a known rogue anti-adware software. Infections shown could be ficticious and the user would of course need to purchase the full version of the software in order to remove the ‘infections’.
Today, for educational purposes, I share my notes from the dissection of the registration routine as registering rogues such as this often makes it easier to remove.
VirusTotal Results
First Run
- Registration calls for an email address and a serial number
Finding the Routine
-
Before we click ‘Enter Activation’ we will load up x32dbg and attach to AdWareALERT
-
Upon clicking the Activation button, we are greeted with an error message
- x32dbg –> right click –> search for strings in all modules –> ‘serial key’
- Double clicking to view in disassembly, ctrl-A to run analysis and we can see that a JMP instruction has brought us to this bad location. Let’s follow it up and see where it came from.
- Scrolling way up we can see one of two jmps that have jumped over the successful reg msg and to the bad msg. Let’s set a break point on the two calls above the jmps.
- Scrolling even further up we can see the likely start of the registration routine. We will breakpoint this location and attempt to register once again.
- As we attempt to register again, we break at the beginning of registration routine. Stepping(f8) through the code, we eventually end up here. We can see an interesting string being pushed before a Call. We took some time to step into the first call (red) and found it was very short and uninteresting. The next call (green) to eax was much more interesting. Let’s step inside of that call and find what looks to be the actual serial creation routine.
Understanding the Routine
- Inside of the Call, we notice that some interesting things are happening. Our email string converted to upper case and stepping through this code, we reach this point where some hard coded values are being moved into addresses based on ESP.
There is an error in the image below. 0x5C is moved to esp+3C and esp+48. But, 0x10 is moved to esp+28
- After all of these moves we will have the following in memory:
- ESP = 0018D384
Address | esp+28 | esp+34 | esp+38 | esp+3C | esp+40 | esp+44 | esp+48 | esp+4C | esp+50 | esp+54 | esp+58 | esp+5C | esp+60 | esp+64 | esp+68 | esp+6C | esp+70 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Value | 0x10 | 0xC | 0x2C | 0x5C | 0x99 | 0x83 | 0x5C | 0x9C | 0x11 | 0xBC | 0x4D | 0x54 | 0x4F | 0x65 | 0x35 | 0xC6 | 0x64 |
- Following the code further, we come to two loops that look interesting (pink & blue). Followed by some math operations (green box).
- Final third loop
Coding the Keygen
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
'''
.hardlyprogramming
This code could most definitely be optimized. I simply followed the assembly for the
most part and favored readability. I think?
'''
# initialize some variables
C1 = 'A493N36S1QQBTC80'
C2 = [0xc, 0x2c, 0x5c, 0x99, 0x83, 0x5c, 0x9c, 0x11, 0xbc, 0x4d, 0x54, 0x4f, 0x65, 0x35, 0xc6, 0x64]
email = input('Enter Email Address: ')
email = email.upper()
loop1_mem = [0,0,0,0,0,0,0,0]
loop2_mem = [0,0,0,0,0,0,0,0]
sum1 = 0
sum2 = 0
sum_total = 0
sk = []
eax=0
# LOOP 1
for letter in email:
temp_val = ord(letter) + 0x12
loop1_mem[eax] = loop1_mem[eax] ^ temp_val
sum1 += loop1_mem[eax]
eax += 1
if eax == 8:
eax = 0
# LOOP 2
for letter in C1:
temp_val = ord(letter) + 0x19
loop2_mem[eax] = loop2_mem[eax] ^ temp_val
sum2 += loop2_mem[eax]
eax += 1
if eax == 8:
eax = 0
# cumulative sum
sum_total = sum1 + sum2
sum_total = sum_total & -2147483137 #0x800001ff
# check if signed and act accordingly
if sum_total < 0:
sum_total -= 1
sum_total |= -512 #0xfffffe00
sum_total += 1
#print('sum: ', sum_total)
eax = 0
# LOOP 3
while eax < 8:
loop2_mem[eax] = loop2_mem[eax] ^ C2[eax]
temp_val = loop2_mem[eax]
temp_val = temp_val ^ loop1_mem[eax]
temp_val = temp_val & -2147483137 #0x800001ff
if temp_val < 0:
temp_val -= 1
temp_val |= -512
temp_val += 1
temp_val = temp_val - sum_total
if temp_val < 0:
temp_val *= -1
if temp_val > 255:
# shift right 4 bits
temp_val = temp_val >> 4
eax +=1
# append hex value as upper without '0x'
sk.append('{:02X}'.format(temp_val))
# i'm lazy
serial = '-'.join([''.join(sk[i:i+2]) for i in range(0, len(sk), 2)])
print(f'Email: {email}')
print(f'Serial: {serial}')