modified FLEXlm by UNIGRAPHICS |
Not Assigned |
|
|
|
|
|
|
Yes. FLEXlm for newbies. Presented by UNIGRAPHICS.
|
When you are interested in CAD software you may have noticed that UNIGRAPHICS released free software named SolidEdgeOrigin. This well programmed software uses the latest parasolid engine. However the UGs added some non-functionality to this program. You will create a model - all OK. You can save it to disk, 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?
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, W32Dasm or IDA 3.75, brain
and other essays on FLEXlm.
|
http://www.ugsolutions.com, http://www.solid-edge.com /*ask
for your free CD*/
|
FLEXlm Tutorials /*globetrotter*/
|
Our target uses 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 intoW32Dasm and look at the exports :- FLEX__enter is the most near to lc_init(). Put a breakpoint on the entry to this function. /* Tip for newbies - use the addr command after the application starts */. 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
After running again the target. I used part.exe file. You will get a message -8,130 - error. And another that you don't have a 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
100015DD XOR EAX, EAX ; bad user - no license
Run it with your valid license number obtained from UGs. You will see the difference...Run the Part.exe with your fake license number and when you bpx 100015CB in part.exe something strange happens. I'm talking 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
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
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 [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 information 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 no feature
.
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 change the jump to NOP's at 5A00C993 but the license is still not available. So step into call 5A010480.
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 pointer - 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 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
.
.
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...
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.
Patch the location in ugflex at 04E53833 to some NOP's. And of course keep the fake license file in the directory. The part.exe you can overwrite with the 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 NOP's. You will get the complete copy of SolidEdge 7.0 - YES all modules!!!.
|
This is a nice example of commercial stupidity - how to license a feature or how to make more money with less effort. Poor programmers if you are reading this, you should improve your product and sell it at a 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*/.