|
UGFLEX
modified flexlm by UNIGRAPHICS
|
 Not Assigned
|
15.11.1999
| by
macilaci
|
|
 |
Courtesy of Fravia's page of
reverse engineering
|
slightly edited
by tsehp |
|
There is a crack, a crack in everything
That's how the light gets in
| |
Rating
|
(X)Beginner (X)Intermediate ( )Advanced ( )Expert
| |
YES. Flexlm for newbies. Presented by UNIGRAPHICS.
UGFLEX
modified flexlm by UNIGRAPHICS
Written by
macilaci
When you are interested in CAD software you may noticed, that UNIGRAPHICS company released
a free software named SolidEdgeOrigin. This well programmed software uses the latest parasolid engine.
However the UGs added some nonfunctionality to this program. You will create a model - all ok.
You can save it to disk /yeah..you think../, but when you create a drawing from the model....
You will be unable to save the drawing- UG starts asking for money. And this makes the soft unusable.
Why create the model when you are unable to make drawings from that? The answer is the marketing strategy.
AutoCad users should learn a new approach... Do you guess it now?
Anyway, you will come to a point when you decide whether to buy the license for SolidedgeOrigin3D or not.
Softice or any other win32 debugger,
Wdasm or IDA 3.75
brain and essays on flexlm /*S+H,pillgrim,etc.*/
http://www.ugsolutions.com,
http://www.solid-edge.com /*ask for your free CD*/
flexlm.../*globetrotter*/
Part One
Our target uses the Globetrotter's flexlm protection. When you have the
license key for SolidEdgeOrigin create
a license file using SolidEdge registration wizard. The license file looks
like this:
FEATURE solidedgeorigin uglmd 7.0 permanent uncounted XXXXXXXXXXXX \
HOSTID=ANY
The XXXXXXXXXXX is your CD key /*hexadecimal numbers*/.
Let's load the ugflex.dll to Wdasm and look at the exports: FLEX__enter is
the most near to the lc_init in noticed essays. Put a breakpoint on the entry
to this fuction. /* Tip for newbies - use the addr command after application start*/
Get your feature names. On the FLEX__enter dd eax and voila...
Create a fake license file: /* Selicense.dat*/
FEATURE solidedgeorigin uglmd 7.0 permanent uncounted 123456789123 \
HOSTID=ANY
FEATURE solidedgeorigin3d uglmd 7.0 permanent uncounted 123456789123 \
HOSTID=ANY
FEATURE solidedgeboxset uglmd 7.0 permanent uncounted 123456789123 \
HOSTID=ANY
FEATURE solidedgeclassic uglmd 7.0 permanent uncounted 123456789123 \
HOSTID=ANY
FEATURE solidedgeassembly uglmd 7.0 permanent uncounted 123456789123 \
HOSTID=ANY
FEATURE solidedgesheetmetal uglmd 7.0 permanent uncounted 123456789123 \
HOSTID=ANY
FEATURE solidedgexpresroute uglmd 7.0 permanent uncounted 123456789123 \
HOSTID=ANY
FEATURE solidedgefeaturereco uglmd 7.0 permanent uncounted 123456789123 \
HOSTID=ANY
Part Two
After this run again the target. I used the part.exe file. You will get a
message -8,130 - error. And another one that you don't have any valid license.
Run it again this time with bpx on FLEX__enter.
Press F12 until you get to part.exe module.
10001568 mov edx, [esp+24h+var_20]
1000156C push edx
1000156D call j_JUTIL_1101
10001572 test eax, eax ; our landing point
10001574 jl short loc_100015BE ;jump
.
.
.
100015BE lea ecx, [esp+28h+var_24]
100015C2 push ecx
100015C3 call j_JUTIL_700
100015C8 add esp, 4
100015CB test eax, eax
100015CD jnz short loc_100015DD ;jump
100015CF test esi, esi
100015D1 jz short loc_100015DD ;jump
100015D3 mov eax, 1 ;load dll's and run it
100015D8 pop esi
100015D9 add esp, 20h
100015DC retn
100015DD xor eax, eax ;bad user - no license
100015DF pop esi
Run it with your valid license number obtained from UGs. You will see the difference...
Run the Part.exe with your fake license number. But what, when you bpx on the 100015CB in the part.exe
some strange thing happen. Yes I speak about this page fault. Let's clear the bpx and run it.
All is OK. You will get the -8,130 message. Do you feel the CRC check? Yes I guessed it too. Do the bpx 100015CB
again but this time with bpm 100015CB.
10001501 mov edx, eax
10001503 xor ebx, ebx
10001505 mov bl, [ecx] ; you land here before the page fault
10001507 and edx, 0FFh
1000150D xor edx, ebx
1000150F shr eax, 8
10001512 mov edx, dword_10006054[edx*4]
10001519 xor eax, edx
1000151B inc ecx
1000151C dec esi
1000151D jnz short loc_10001501
1000151F pop ebx
10001520 not eax
10001522 pop esi
10001523 retn
Get one level up with F12. You see:
10001715 mov edx, dword_10006C78
1000171B mov eax, dword_10006C74
10001720 push edx
10001721 push eax
10001722 call sub_100014F0 ;our call
10001727 mov ecx, dword_10006C7C ;load the correct CRC
1000172D add esp, 8
10001730 cmp eax, ecx ;compare
10001732 jz loc_10001819 ;jump if OK
.
.
1000174E push offset aCrcBuffer_8xCo ;bad boy
10001753 push eax
10001754 call ds:sprintf
1000175A add esp, 14h
1000175D lea ecx, [esp+540h+var_20C]
10001764 push ecx
10001765 call ds:OutputDebugStringA
Another exples: Bpx in Jutil.dll module. The CRC check is done right
before the our part.exe CRC check:
100016C6 push 3BF0h
100016CB push eax
100016CC call sub_100014F0
100016D1 add esp, 8
100016D4 cmp eax, 464E4B2Eh ;looks like CRC
100016D9 jnz loc_1000176B ;jump if bad
100016DF lea ecx, [esi+1350h]
100016E5 push 130h
100016EA push ecx
100016EB call sub_100014F0
100016F0 add esp, 8
100016F3 cmp eax, 1A78AC1Ch ;this too
100016F8 jnz short loc_1000176B
100016FA add esi, 3A1F0h
10001700 push 0D8h
10001705 push esi
10001706 call sub_100014F0
1000170B add esp, 8
1000170E cmp eax, 4D03231Ah ;oops
10001713 jnz short loc_1000176B
To keep our debugging session comfortable modify the jumps.
Let's continue with our BPX 100015CB.
1000156C push edx
1000156D call j_JUTIL_1101
10001572 test eax, eax ; our old landing point
10001574 jl short loc_100015BE ;jump if bad
.
.
.
100015BE lea ecx, [esp+28h+var_24]
100015C2 push ecx
100015C3 call j_JUTIL_700
100015C8 add esp, 4
100015CB test eax, eax
100015CD jnz short loc_100015DD ;jump if bad
100015CF test esi, esi
100015D1 jz short loc_100015DD ;jump if bad
Examine the JUTIL_700 call - you will see that this is just playing with
numbers. The real deal is the JUTIL_1101.
Bpx there and step in...
5A00F870 sub esp, 20h
5A00F873 lea eax, [esp+20h+var_20]
5A00F877 mov [esp+20h+var_1C], offset loc_5A00C690
;create jump table
5A00F87F push eax
5A00F880 mov [esp+24h+var_18], offset loc_5A00CDB0 ;create jump table
5A00F888 mov [esp+24h+var_14], offset loc_5A00D4D0 ;create jump table
5A00F890 mov [esp+24h+var_10], offset loc_5A00DBF0 ;create jump table
5A00F898 mov [esp+24h+var_C], offset loc_5A00E310 ;create jump table
5A00F8A0 mov [esp+24h+var_8], offset loc_5A00EA30 ;create jump table
5A00F8A8 mov [esp+24h+var_4], offset loc_5A00F150 ;create jump table
5A00F8B0 call ds:time ;get random value
5A00F8B6 mov eax, [esp+24h+var_20]
5A00F8BA mov ecx, 7
5A00F8BF cdq
5A00F8C0 idiv ecx
5A00F8C2 mov eax, [esp+24h+arg_0] ;reduced to 7 cases
5A00F8C6 push eax
5A00F8C7 call [esp+edx*4+28h+var_1C] ;jump
5A00F8CB add esp, 28h
5A00F8CE retn 4
As you see the the code at different locations is the same. What does this
mean ? Answer: To gather newbies getting informations about this target.
You can set the edx value to zero.
Step in the 5A00C690.
5A00C8FA loc_5A00C8FA: ; CODE XREF: .text:5A00CA8B_j
5A00C8FA mov ecx, [esp+3Ch]
5A00C8FE add ecx, edi
5A00C900 cmp [ecx+10h], ebx
5A00C903 jz loc_FFFFF000_5A00CA78 ;jump if nofeature
.
.
5A00CA78 mov edi, [esp+10h]
5A00CA7C mov ecx, [esp+40h]
5A00CA80 inc ebp
5A00CA81 add edi, 14h
5A00CA84 dec ecx
5A00CA85 mov [esp+10h], edi
5A00CA89 cmp ebp, ecx ;all licenses checked?
5A00CA8B jle loc_5A00C8FA ;jump if not
And inside this cycle /*if the name of feature was found*/:
5A00C987 push eax
5A00C988 push ecx
5A00C989 call sub_5A010480 ;check license
5A00C98E add esp, 2Ch
5A00C991 test eax, eax ;it's OK?
5A00C993 jz short loc_5A00C9DE ;jump if not
5A00C995 mov edx, [esp+40h]
5A00C999 lea esi, [ebp+1]
5A00C99C dec edx
5A00C99D cmp esi, edx
5A00C99F jg loc_5A00CA78
You can set the jump to nops at 5A00C993 but the license is still not
available. So step into the 5A010480 call.
5A010508 mov ecx, dword_5A03CBB4
5A01050E push eax
5A01050F call sub_5A026660 ; compare license
5A010514 mov ebx, eax
5A010516 lea ecx, [esp+9Ch+var_5C]
5A01051A mov byte ptr [esp+9Ch+var_4], 4
5A010522 call ??1GUserText@@QAE@XZ
Look at the eax poiter - our feature names, step into 5A026660.
5A026691 mov ecx, [esp+2Ch+arg_4]
5A026695 push ecx
5A026696 push edx
5A026697 call j_FLEX__set_product_version
5A02669C lea eax, [esp+34h+var_20]
5A0266A0 push 1
5A0266A2 push eax
5A0266A3 call j_FLEX__enter ;we started here
5A0266A8 add esp, 10h
5A0266AB mov ecx, ebx
5A0266AD mov esi, eax
5A0266AF call sub_5A026D50
5A0266B4 mov ecx, [esp+2Ch+arg_8]
5A0266B8 test esi, esi
5A0266BA mov [ecx], eax
5A0266BC jnz short loc_5A0266DA
5A0266BE lea edx, [esp+2Ch+var_20] ; license ok, continue
Don't modify the jump - it doesn't make any sense, just step into a
FLEX_enter.
04E514EE push esi
04E514EF mov esi, [esp+4+arg_0]
04E514F3 push esi
04E514F4 push offset aEnteringModule ; entering module
04E514F9 call FLEX__note
04E514FE mov eax, dword_4E81DA8
04E51503 push 4000h
04E51508 push offset unk_4E7C130
04E5150D push 0
04E5150F push 1
04E51511 push offset a15_0
04E51516 push esi
04E51517 push eax
04E51518 mov dword_4E80410, 1
04E51522 call sub_4E53481 ;yep , this call - step in
04E51527 mov esi, eax
04E51529 add esp, 24h
04E5152C test esi, esi
04E5152E jge short loc_4E51552
04E51530 cmp [esp+4+arg_4], 1
04E51535 jnz short loc_4E51540
04E51537 push esi
04E51538 call sub_4E519E0 ; ugflexlmerror
04E53481...
.
.
.
04E534F5 mov dword_4E80948, offset 04E53669
04E534FF or byte ptr [esi+17Ch], 40h
04E53506 push esi
04E53507 call dword_4E80948 ;step in
An indirect call - this might be...
04E53669...
.
.
.
04E53827 push edi
04E53828 push esi
04E53829 call sub_4E53E77
04E5382E add esp, 0Ch
04E53831 test eax, eax ; eax should not be
zero
04E53833 jz loc_4E53726 ; jump if bad boy
04E53839 cmp dword ptr [ebp+18h], 3
04E5383D jz loc_FFFFF000_4E53924
04E53843 push edi ;license OK -continue
When you patch the jump at 04e53831 you will get the right license for our
fake license file. And how to get this?
I've just compared the jumps with the valid SolidEdgeOrigin key /*remember, it's for free*/.
Here is the jump at location -compare table:
SolidEdgeOrigin Our feature with fake key
04E536A1 04E536A1
04E536D7 04E536D7
04E5371E 04E5371E
04E53749 04E53749
04E5377F 04E5377F
04E537A2 04E537A2
04E537F3 04E537F3
04E53833
etc. etc.
You see - nothing special.
Part three - let's patch it
Patch the location in ugflex at 04E53833 to some nops. And of course keep
the fake license file in the directory. The part.exe you can overwrite with original version.
To prevent lamers from detecting which file was changed /*the about box -
setup info- */ change some bytes in partDcx.dll at 075B77FA to nops.
You will get the complete copy of SolidEdge 7.0 -YES all modules!!!
This is a nice example to show the commercial stupidity - how to license a feature or how to make more money with less effort.
Poor programmers... Dear programmers if you are reading this, you should improve your product and sell it at nice price.
Then more people will buy it /*The effect of scale- ask marketers - they should know it and if not, there's a problem*/.
I wont even bother explaining you
that you should BUY this target program if you intend to use it 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 on most Warez sites, complete and already regged,
farewell, don't come back.
You are deep inside fravia's page of reverse engineering,
choose your way out:
homepage
links
search_forms
+ORC
how to protect
academy database
reality cracking
how to search
javascript wars
tools
anonymity academy
cocktails
antismut CGI-scripts
mail_fravia+
Is reverse engineering legal?