OCX Control Highlights
Licensing schemes
Visual Basic
by +PopJack , 15 January 1998
very slightly edited by reverser+
Courtesy of Reverser's page of reverse engineering
I'm very happy to present you this VERY USEFUL essay by +Popjack, a good teacher for visual basic matters (we host his very good Reverse Engineering VBX Custom Controls essay) that to-day will teach us in an extremely clear manner how easy it is to reverse OCX controls licensing systems. This will not wonder my readers: it is a well know reversing paradox: the more overbloated the language used for a protection scheme, the more easy it is to tackle it "from underneath" and cut its belly with our razor sharp assembly knifes! Here is +Popjack's letter to me:
Well Reverser+, as promised here comes my essay on OCX controls. It really 
doesn't bring any new approaches. It took time but it's difficult to 
find the time to do everything that we want...I mean all that stuff 
about listening to music or reading the classics.
Well, this is sadly very true... until we'll have a more mature society, where each one will be encouraged to study and work on whatever he feels like instead of being only compelled and pushed to turn its silly guinea-pig wheel in order to consume (and waste) useless gadgets, I believe that we'll have to devise some tricks to "reverse" the trend and take (at least in part) control of the time we need... and eliminating the useless TV-watching seems to me the most easy trick of the lot :-)
There is a crack, a crack in everything
That's how the light gets in
(x)Beginner (x)Intermediate ( )Advanced ( )Expert
In this essay my focus is more on the general concepts of ocx licensing control and less on code listings. So I want to give away FOR FREE some of my humble knowledge. I write this hoping that my readers will not just copy what they find in here, I hope that many will start working using these basis so that we'll all be able to use their knowledge to go further and further on our beautiful paths. Remember the old chineese/ORCish saying: Don't give a man a fish. Teach him how to fish instead.
OCX Control Highlights
Written by +PopJack

OCX controls have replaced their VBX counterparts as software 
components to be added to the main applications. The reason is 
that OCX controls can use 32 bit technology while VBX controls 
These controls need to be registered so that the OS can be aware of 
them. That's why they have all some self registering functions built 
inside. But this doesn't mean we can use them whenever we want to. 
For example a control can be used as a part of an application in some 
machine but will not load in the user programming environment (Visual 
Basic for instance) because a licensing scheme, used by the control, 
prevents him to do so.
The reason is that when we try to use a control that uses a licensing 
procedure it will try to find some specific information in our machine. 
If it is not there the control doesn't get loaded.
During the application execution the control can be loaded because 
the application carries inside the necessary info to give to the control 
and allow its loading. 
In brief, let's say that the application generates some lic info or 
lic key (look for RequestLicKey, CreateInstanceLic and GetLicInfo in 
the target's control).
Tools Required
Softice: our main tool
W32dasm: very useful indeed, although not always needed
Hexeditor : I still use Hexpert, but there are very good alternatives (not used here)
Visual Basic: I am using here VB4 16 bit

Program History

We will see now two examples.

Example1: Using a LIC file
Target: Fountain.ocx
Where to find: http://www.soe.bcit.bc.ca/ocx/
When we place the control in a form, an ocx malfunction pops a 
nagscreen which makes one loose its concentration. 
Very disturbing...
So we need to find out what went wrong.
Let's start with a bpx dialogbox (just to start fishing). 
We load the control in the Visual Basic environment and bang... 
We pop into Softice at 0001.1677: 

:0001.1637 C8280000               enter 0028, 00
:0001.163B 1E                     push ds
:0001.163C 8ED8                   mov ds, ax
:0001.163E 9AF5000000             call OC25.Ord{0985h}
:0001.1643 8EC2                   mov es, dx
:0001.1645 8BD8                   mov bx, ax
:0001.1647 26FF7708               push word ptr es:[bx+08]
:0001.164B 0E                     push cs
:0001.164C 68A209                 push 09A2	'Fountain.lic
:0001.164F 0E                     push cs	'Fountain Fill OCX Copyright
:0001.1650 686209                 push 0962

* Possible Reference to Dialog: DialogID_0064, CONTROL_ID:00FF, ""
:0001.1653 6AFF                   push FFFF
:0001.1655 9AFFFF0000             call OC25.Ord{027Eh}
:0001.165A 0BC0                   or ax, ax	'If valid lic file then ax=1 
:0001.165C 7523                   jne 1681	'and we jump above the nag

:0001.165E 68CF00                 push 00CF	'nag screen procedures start 
:0001.1661 50                     push ax
:0001.1662 50                     push ax
:0001.1663 8D46D8                 lea ax, [bp-28]
:0001.1666 16                     push ss
:0001.1667 50                     push ax
:0001.1668 9AFFFF0000             call OC25.Ord{011Bh}
:0001.166D 8D46D8                 lea ax, [bp-28]
:0001.1670 16                     push ss
:0001.1671 50                     push ax
:0001.1672 9AFFFF0000             call OC25.Ord{0373h}  'bpxing the dialogbox
:0001.1677 8D46D8                 lea ax, [bp-28]	'We have landed here!
:0001.167A 16                     push ss
:0001.167B 50                     push ax
:0001.167C 9AFFFF0000             call OC25.Ord{0198h}

:0001.1681 B80100                 mov ax, 0001
:0001.1684 1F                     pop ds
:0001.1685 C9                     leave
:0001.1686 CA0400                 retf 0004

Scrolling up the code we soon find the location where the decision 
is taken. The dead list doesn't give us enough info so we place a 
bpx at 0001.164B to trace from that point on and understand the jne
at 0001.165C (yes, we felt it, but we want to understand).
After doing some tracing around this point we see that after all the 
problem is that a license file called Fountain.lic with a string 
inside seem to be curiously missing.
Ok we can take care of that, in order to avoid further interruptions 
in our programming and/or reversing activities,by preparing a simple 
LIC file with the required string.
Make a note of it: this call to OC25.dll Ord{027Eh} is found in 
many controls that implement such simple licensing scheme. 
The reason is that this procedure is generated automatically by the
control building wizard. Of course the programmer can (and should)
override such a simple verification in order to make things at least 
a little harder. 
Anyway I've used this approach of searching the dead list for this 
call and I can tell you that it works. Simply modify the routine 
0x27E inside OC25.dll (keep a 'sound copy of it as OC25.ori) in 
order to get always ax=1 as a return value and all these targets 
won't bother you anymore with OCX with their funny license files.

Example2: Using the registry or a lic file
Target: Vsocx.ocx
Where to find: http://www.videosoft.com

Ok, let's install the OCX control using the setup prog included in the 
evaluation pack.
Now in the VB environment we try to load the control using the Custom 
Control menu dialog.
The control appears in the control toolbox. Everything seems to be 
When we place one of the 3 controls that come within vsocx we get a 
nag screen telling us where to call to get a registered version. 
That's a bug of course, because this screen is supposed to be shown 
only when we click the about button in the properties window.
So we are here to fix this misplaced call.
As this window does not seem to be a messagebox, so we place a bpx 
dialogbox and wait to see what we fish. 
Unload the control clearing the checkbox on the custom controls menu 
and check it again to get it again in the controls toolbox. 
We try to place the control in the form and ..bang! into Softice we
After some F12's we find ourselves in vsocx16.

* Referenced by a CALL at Address:0002.1EC7
:0002.23D6 B82D24                 mov ax, SEG ADDR of Segment 0005
:0002.23D9 C8280000               enter 0028, 00
:0002.23DD 1E                     push ds
:0002.23DE 8ED8                   mov ds, ax

* Possible Reference to Dialog: DialogID_01F4 
:0002.23E0 68F401                 push 01F4
:0002.23E3 6A00                   push 0000
:0002.23E5 6A00                   push 0000
:0002.23E7 8D46D8                 lea ax, [bp-28]
:0002.23EA 16                     push ss
:0002.23EB 50                     push ax
:0002.23EC 9AFFFF0000             call OC25.Ord{011Bh}
:0002.23F1 8D46D8                 lea ax, [bp-28]
:0002.23F4 16                     push ss
:0002.23F5 50                     push ax
:0002.23F6 9A24BF0000             call OC25.Ord{0373h}
:0002.23FB 48                     dec ax		'We land here!
:0002.23FC 751E                   jne 241C
:0002.23FE C45E06                 les bx, [bp+06]

  The code at this place doesn't feel interesting so we scroll up to 
the begining of this rotine where we place a bpx at the very beginning, 
in order to use  the stack command next time we come by.
Make a note of it: Call OC25.Ord{011Bh} followed by call OC25.Ord{0373h} 
are used in about boxes. 
Once more we unload and load the control into the VB toolbox; place the 
control in a form... bum!
Back into Softice, at our own breakpoint. 
Now we do a stack command. 
Note that from the dead list we also get the caller!
This is where we are:

:0002.1EAC FF7608                 push word ptr [bp+08]
:0002.1EAF 56                     push si
:0002.1EB0 9AD05C5519             call 0001.5CD0
:0002.1EB5 833E520D00             cmp word ptr [0D52], 0 'our friends "compare"
:0002.1EBA 750E                   jne 1ECA               'and "jump if true"
:0002.1EBC C706520D0100           mov word ptr [0D52], 1
:0002.1EC2 FF7608                 push word ptr [bp+08]
:0002.1EC5 56                     push si
:0002.1EC6 0E                     push cs
:0002.1EC7 E80C05                 call 23D6		  'This call starts 
							  'the nag screen
:0002.1ECA 1F                     pop ds
:0002.1ECB 5E                     pop si
:0002.1ECC C9                     leave
:0002.1ECD CA1000                 retf 0010

What controls the unwanted call? 
Obviously the cmp word ptr [0D52]
Is it written somewhere during the loading of the control?
Let's find out with a bpm ds:0d52
Unload and load the control blá blá blá...
Aha! Now this is interesting...

:0001.B9C6 B837A6                 mov ax, SEG ADDR of Segment 0005
:0001.B9C9 C8080000               enter 0008, 00
:0001.B9CD 1E                     push ds
:0001.B9CE 8ED8                   mov ds, ax
:0001.B9D0 833E520D00             cmp word ptr [0D52], 0000
:0001.B9D5 757D                   jne BA54		<------- HERE! :0001.B9D7 6A00 push 0000 :0001.B9D9 6A01 push 0001 :0001.B9DB 1E push ds :0001.B9DC 683204 push 0432 :0001.B9DF 8D46FC lea ax, [bp-04] :0001.B9E2 16 push ss :0001.B9E3 50 push ax :0001.B9E4 9AFDB90000 call SHELL.REGOPENKEY :0001.B9E9 0BD0 or dx, ax :0001.B9EB 7537 jne BA24 :0001.B9ED FF76FE push word ptr [bp-02] :0001.B9F0 FF76FC push word ptr [bp-04] :0001.B9F3 0E push cs :0001.B9F4 6885A8 push A885 'Licenses :0001.B9F7 8D46F8 lea ax, [bp-08] :0001.B9FA 16 push ss '87CFB907-3C1D-11d0- :0001.B9FB 50 push ax '8ACC-44455354000 :0001.B9FC 9AFFFF0000 call SHELL.REGOPENKEY :0001.BA01 0BD0 or dx, ax 'ax="dx=0" means no errors :0001.BA03 7514 jne BA19 :0001.BA05 B80100 mov ax, 0001 :0001.BA08 A3520D mov word ptr [0D52], ax 'Flag don't show nag :0001.BA0B A3500D mov word ptr [0D50], ax :0001.BA0E FF76FA push word ptr [bp-06] :0001.BA11 FF76F8 push word ptr [bp-08] :0001.BA14 9A20BA0000 call SHELL.REGCLOSEKEY | :0001.BA19 FF76FE push word ptr [bp-02] :0001.BA1C FF76FC push word ptr [bp-04] :0001.BA1F 9AFFFF0000 call SHELL.REGCLOSEKEY Look! The control is trying to open a registry key. If not found it proceeds to the next check. So we place a bpx on location 0001:B9ED and trace from that point on. Ok, at B9FC we are done. Like +ORC says its more than enough, thank you. We edit the registry and add a key 87CFB907-3C1D-11d0-8ACC-44455354000 under HKEY_CLASSES_ROOT\Licenses (or we can prepare a reg file with this key). Make a note of it: License info resides in HKEY_CLASSES_ROOT\Licenses But what happens if this check fails? Look at what we have next to the above snippet: | :0001.BA24 833E520D00 cmp word ptr [0D52], 0000 :0001.BA29 7529 jne BA54 :0001.BA2B 9AB7A30000 call OC25.Ord{0985h} :0001.BA30 8EC2 mov es, dx :0001.BA32 8BD8 mov bx, ax :0001.BA34 26FF7708 push word ptr es:[bx+08] :0001.BA38 1E push ds :0001.BA39 684B04 push 044B 'vsocx.lic :0001.BA3C 1E push ds 'VideoSoft vsOcx :0001.BA3D 683B04 push 043B :0001.BA40 6AFF push FFFF :0001.BA42 9AFFFF0000 call OC25.Ord{027Eh} :0001.BA47 0BC0 or ax, ax :0001.BA49 7409 je BA54 :0001.BA4B B80100 mov ax, 0001 :0001.BA4E A3520D mov word ptr [0D52], ax 'Flag don't show nag :0001.BA51 A3500D mov word ptr [0D50], ax :0001.BA54 B80100 mov ax, 0001 :0001.BA57 1F pop ds :0001.BA58 C9 leave :0001.BA59 CA0400 retf 0004 Seeing this I understand what +ORC was speaking about when he talked about feeling the code. Can you see (feel) it? :0001.BA42 9AFFFF0000 call OC25.Ord{027Eh} <-- our old friend 27E It is the string that is supposed to be found in a valid license file! Remember what I said earlier about the OC25.Ord{027Eh} call? Some other controls I found use instead "Cinderella" protection schemes that can be pinpointed with the usual approach of GetSystemTime and related API calls. 
OCX controls seem to be poorly protected from what we have 
seen here. 
There are of course several ways to pinpoint these components. 
Instead of showing you a way to get along with a specific control 
I want to give you a general idea of the concepts regarding ocx 
licensing control from the point of vue of a +HCU study. 
We will see in the near future more interesting things to work on, 
like digital signatures of activeX controls, which are dowloaded 
by all web browsers when they show some html pages. 

Thanks to +ORC and the +HCU fellows, who taught me 99% of what 
I know. Well... I've also learned something by myself I must say.
I thank again Reverser+ for maintaining his site with such powerful 
information, and a special thanks goes to +ReZiDeNt for his help.

(c) +PopJack    15 January 1998
Ob duh
I wont even bother explaining you that you should BUY these target programs if you intend to use them for a longer period than the allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it of course on any good Warez site, complete and already regged, farewell.
way out
You are deep inside reverser's page of reverse engineering, choose your way out:

Visual basic
Back to Visual Basic
redhomepage redlinks redanonymity +ORC redstudents' essays redacademy database
redtools redcocktails redantismut CGI-scripts redsearch_forms redmail_reverser
redIs reverse engineering legal?