Log in

View Full Version : understanding disassembler lc_init


NoLOcKs
March 22nd, 2007, 08:08
From VoxQuietis´s essay "How to make V5.x license files with the V6.x SDK"
We learned that can to recoverer vkey 1..4 plus XORed seeds 1 and 2. So i disassembled the function lc_init. Now go the question: Where I get this data into file dissambled ?

Suggests are wellcome !



.text:1000E850 public lc_init
.text:1000E850 lc_init proc near
.text:1000E850
.text:1000E850
.text:1000E850 var_1A0 = dword ptr -1A0h
.text:1000E850 var_19C = dword ptr -19Ch
.text:1000E850 var_198 = dword ptr -198h
.text:1000E850 var_194 = dword ptr -194h
.text:1000E850 var_190 = dword ptr -190h
.text:1000E850 arg_0 = dword ptr 4
.text:1000E850 arg_4 = dword ptr 8
.text:1000E850 arg_8 = dword ptr 0Ch
.text:1000E850 arg_C = dword ptr 10h
.text:1000E850
.text:1000E850 sub esp, 1A0h
.text:1000E856 mov [esp+1A0h+var_198], 1
.text:1000E85E push ebx
.text:1000E85F push esi
.text:1000E860 push edi
.text:1000E861 xor esi, esi
.text:1000E863 mov [esp+1ACh+var_194], esi
.text:1000E867 push ebp
.text:1000E868 mov [esp+1B0h+var_1A0], esi
.text:1000E86C cmp [esp+1B0h+arg_0], esi
.text:1000E873 jz short loc_1000E8C2
.text:1000E875 mov eax, [esp+1B0h+arg_0]
.text:1000E87C push 1Dh
.text:1000E87E push eax
.text:1000E87F call l_getattr
.text:1000E884 add esp, 8
.text:1000E887 cmp eax, 9969h
.text:1000E88C jz short loc_1000E8C2
.text:1000E88E mov eax, [esp+1B0h+arg_0]
.text:1000E895 cmp dword ptr [eax], 67h
.text:1000E898 jz short loc_1000E8C2
.text:1000E89A cmp eax, esi
.text:1000E89C jz short loc_1000E8B2
.text:1000E89E cmp dword ptr [eax+4], 0FFFFFFD8h
.text:1000E8A2 jz short loc_1000E8B2
.text:1000E8A4 mov dword ptr [eax+4], 0FFFFFFD3h
.text:1000E8AB mov dword ptr [eax+1Ch], 0B2h
.text:1000E8B2
.text:1000E8B2 loc_1000E8B2: ; CODE XREF: lc_init+4C j
.text:1000E8B2 ; lc_init+52 j
.text:1000E8B2 mov eax, 0FFFFFFD3h
.text:1000E8B7 pop ebp
.text:1000E8B8 pop edi
.text:1000E8B9 pop esi
.text:1000E8BA pop ebx
.text:1000E8BB add esp, 1A0h
.text:1000E8C1 retn

gerbay
March 22nd, 2007, 08:52
you can use lmkg.exe (flexlm vendor key generator) for creating vendor keys for given "Vendor Name" and you can focus "_l_svk" method for finding encryption seeds..

NoLOcKs
March 22nd, 2007, 14:49
This i already knew. But how i can to find the l_sg into lmgr5a.dll. I don´t see.
Anyone can help me ??

gerbay
March 22nd, 2007, 15:48
where is lmgr5a.dll, I didn't see it.. I have v6.1 SDK but i didn't see.. please upload dll or which SDK version includes lmgr5a.dll?

NoLOcKs
March 22nd, 2007, 17:54
I upload lmgr5a.dll. See if u discover the function l_sg

gerbay
March 22nd, 2007, 18:57
for version 5.x, the important function is "l_svk", not "l_sg"!

Code:


.text:1000B8A2 E8 C9 7C FF FF call l_check
.text:1000B8A7 83 C4 20 add esp, 20h
.text:1000B8AA
.text:1000B8AA loc_1000B8AA: ; CODE XREF: _l_ok+5Fj
.text:1000B8AA 5D pop ebp
.text:1000B8AB 5F pop edi
.text:1000B8AC 5E pop esi
.text:1000B8AD 5B pop ebx
.text:1000B8AE 83 C4 04 add esp, 4
.text:1000B8B1 C3 retn
.text:1000B8B1 _l_ok endp
.text:1000B8B1
.text:1000B8B1 ; ---------------------------------------------------------------------------
.text:1000B8B2 CC CC CC CC CC CC+ align 10h
.text:1000B8C0
.text:1000B8C0 ; =============== S U B R O U T I N E =======================================
.text:1000B8C0
.text:1000B8C0
.text:1000B8C0 _l_svk proc near ; CODE XREF: _l_handshake+1Bp
.text:1000B8C0 ; _l_handshake_0+29p
.text:1000B8C0 ; _good_lic_key+20p
.text:1000B8C0 ; _good_lic_key+DDp
.text:1000B8C0 ; lc_feat_set+84p
.text:1000B8C0 ; l_cksum+16p
.text:1000B8C0 ; _cryptfeaturelist+D7p
.text:1000B8C0
.text:1000B8C0 sig3 = byte ptr -4
.text:1000B8C0 sig2 = byte ptr -3
.text:1000B8C0 sig1 = byte ptr -2
.text:1000B8C0 sig0 = byte ptr -1
.text:1000B8C0 vendor_id= dword ptr 4
.text:1000B8C0 VENDOR_CODE= dword ptr 8
.text:1000B8C0
.text:1000B8C0 8B 44 24 08 mov eax, [esp+VENDOR_CODE]
.text:1000B8C4 83 EC 04 sub esp, 4
.text:1000B8C7 83 C0 0C add eax, 0Ch
.text:1000B8CA 56 push esi
.text:1000B8CB 8B 74 24 0C mov esi, [esp+8+vendor_id]
.text:1000B8CF 50 push eax
.text:1000B8D0 56 push esi
.text:1000B8D1 E8 4A CC FF FF call _l_key
.text:1000B8D6 83 C4 08 add esp, 8
.text:1000B8D9 85 C0 test eax, eax
.text:1000B8DB 75 07 jnz short loc_1000B8E4
.text:1000B8DD 33 C0 xor eax, eax
.text:1000B8DF 5E pop esi
.text:1000B8E0 83 C4 04 add esp, 4
.text:1000B8E3 C3 retn
.text:1000B8E4 ; ---------------------------------------------------------------------------
.text:1000B8E4
.text:1000B8E4 loc_1000B8E4: ; CODE XREF: _l_svk+1Bj
.text:1000B8E4 B9 03 00 00 00 mov ecx, 3
.text:1000B8E9 33 D2 xor edx, edx
.text:1000B8EB 88 54 24 07 mov [esp+8+sig0], dl
.text:1000B8EF 88 54 24 06 mov [esp+8+sig1], dl
.text:1000B8F3 88 54 24 05 mov [esp+8+sig2], dl
.text:1000B8F7 88 54 24 04 mov [esp+8+sig3], dl
.text:1000B8FB 38 16 cmp [esi], dl
.text:1000B8FD 74 14 jz short loc_1000B913
.text:1000B8FF
.text:1000B8FF loc_1000B8FF: ; CODE XREF: _l_svk+51j
.text:1000B8FF 8A 16 mov dl, [esi] ; vendor_id indexed by esi
.text:1000B901 46 inc esi
.text:1000B902 30 54 0C 04 xor [esp+ecx+8+sig3], dl
.text:1000B906 49 dec ecx
.text:1000B907 79 05 jns short loc_1000B90E
.text:1000B909 B9 03 00 00 00 mov ecx, 3
.text:1000B90E
.text:1000B90E loc_1000B90E: ; CODE XREF: _l_svk+47j
.text:1000B90E 80 3E 00 cmp byte ptr [esi], 0
.text:1000B911 75 EC jnz short loc_1000B8FF
.text:1000B913
.text:1000B913 loc_1000B913: ; CODE XREF: _l_svk+3Dj
.text:1000B913 0F BE 54 24 07 movsx edx, [esp+8+sig0]
.text:1000B918 0F BE 4C 24 05 movsx ecx, [esp+8+sig2]
.text:1000B91D C1 E2 10 shl edx, 10h
.text:1000B920 0B D1 or edx, ecx
.text:1000B922 0F BE 74 24 04 movsx esi, [esp+8+sig3]
.text:1000B927 0F BE 4C 24 06 movsx ecx, [esp+8+sig1]
.text:1000B92C C1 E2 08 shl edx, 8
.text:1000B92F C1 E1 10 shl ecx, 10h
.text:1000B932 0B D1 or edx, ecx
.text:1000B934 0B D6 or edx, esi
.text:1000B936 33 50 08 xor edx, [eax+8] ; edx = signature, [eax+8] = keys1
.text:1000B939 33 50 04 xor edx, [eax+4] ; edx = signature, [eax+4] = keys2
.text:1000B93C 81 F2 30 87 F3 A8 xor edx, 0A8F38730h ; version 5 magic number
.text:1000B942 8B C2 mov eax, edx ; eax = signature
.text:1000B942 ; (signature means vendorKey5)
.text:1000B944 85 C0 test eax, eax
.text:1000B946 75 05 jnz short loc_1000B94D
.text:1000B948 B8 30 87 F3 A8 mov eax, 0A8F38730h ; if (signature == 0)
.text:1000B948 ; return version 5 magic number
.text:1000B94D
.text:1000B94D loc_1000B94D: ; CODE XREF: _l_svk+86j
.text:1000B94D 5E pop esi
.text:1000B94E 83 C4 04 add esp, 4
.text:1000B951 C3 retn
.text:1000B951 _l_svk endp
.text:1000B951
.text:1000B951 ; ---------------------------------------------------------------------------
.text:1000B952 CC CC CC CC CC CC+ align 10h
.text:1000B960 ; Exported entry 35. lc_ck_feats
.text:1000B960
.text:1000B960 ; =============== S U B R O U T I N E =======================================
.text:1000B960
.text:1000B960
.text:1000B960 public lc_ck_feats
.text:1000B960 lc_ck_feats proc near
.text:1000B960
.text:1000B960 arg_0 = dword ptr 10h
.text:1000B960 arg_4 = dword ptr 14h
.text:1000B960
.text:1000B960 53 push ebx
.text:1000B961 56 push esi
.text:1000B962 57 push edi
.text:1000B963 33 DB xor ebx, ebx
.text:1000B965 8B 74 24 10 mov esi, [esp+arg_0]
.text:1000B969 55 push ebp
.text:1000B96A 6A 13 push 13h
.text:1000B96C 56 push esi
.text:1000B96D E8 4E BD FF FF call _l_getattr
.text:1000B972 83 C4 08 add esp, 8



NoLOcKs
March 22nd, 2007, 20:29
What .dll that you used above? In .dll that i upload don´t have these functions ( l_svk, l_key, l_good_lic_key) and others.

FoxB
March 22nd, 2007, 22:57
If u have valid vkeys and seeds for v6.x - build lmcrypt.exe from v6.x SDK.
Now run it as
'lmcrypt.exe - verfmt 5 -i input_file -o output_file'
or
'lmcrypt.exe - verfmt 5.1 -i input_file -o output_file'

wbr

gerbay
March 23rd, 2007, 03:31
Quote:
[Originally Posted by NoLOcKs;64542]What .dll that you used above? In .dll that i upload don´t have these functions ( l_svk, l_key, l_good_lic_key) and others.


I used lmgr325a.dll which is uploaded by yours..

Exported entry 35. is "lc_ck_feats" method in lmgr325a.dll and the previous method is "l_svk" method..

detailed description given by me in my previous post, please read line comments. also "l_svk" method's callers given in assembly code..
---
methods:
exported entry 35 - 2 => "_l_ok" method (it is not an exported function)
exported entry 35 - 1 => "_l_svk" method (it is not an exported function)
exported entry 35 ====> : "_lc_ck_feats" method (exported function)
exported entry 35 + 1 = exported entry 33 => "_lc_checkin" method (exported function)
exported entry 35 + 2 = exported entry 42 => "_l_flush_config" method (exported function)
...
---

NoLOcKs
March 23rd, 2007, 14:41
Very good, Gerbay

I´m feeling that are near of end of your adventure. it is missing little.
Sorry for my ignorance,but i still need to finding some data to get encryption seed 1,2:

data[0]
data[1]
job + 8
job + C
job + 10

Where exactly i put breakpoints to recovery these values !

gerbay
March 23rd, 2007, 17:30
you should trace this code in your debugger which is given below.
this function contains vendor's seeds..
so, I think; may be you don't need data[0], data[1] and job structure..

if you want to try to hard way, you can put breakpoint all l_svk method caller functions and inspect stack variables..

you can find this code very easy, address is ".text:10018380"..
please read my comments...

Code:

.text:10018380 lg_encrypt proc near ; CODE XREF: _l_handshake+3Bp
.text:10018380
.text:10018380 seedBuff= dword ptr -140h
.text:10018380 str = byte ptr -128h
.text:10018380 keys = dword ptr -94h
.text:10018380 pszMSG = dword ptr 4
.text:10018380 seed_1 = dword ptr 8
.text:10018380 seed_2 = dword ptr 0Ch
.text:10018380
.text:10018380 81 EC 40 01 00 00 sub esp, 140h
.text:10018386 33 C0 xor eax, eax
.text:10018388 B9 24 00 00 00 mov ecx, 24h
.text:1001838D 53 push ebx
.text:1001838E 56 push esi
.text:1001838F 57 push edi
.text:10018390 8B B4 24 50 01 00 00 mov esi, [esp+14Ch+pszMSG]
.text:10018397 8B FE mov edi, esi
.text:10018399 F3 AB rep stosd
.text:1001839B 66 AB stosw
.text:1001839D AA stosb
.text:1001839E 8B 84 24 58 01 00 00 mov eax, [esp+14Ch+seed_2]
.text:100183A5 8B 8C 24 54 01 00 00 mov ecx, [esp+14Ch+seed_1]
.text:100183AC 8D 54 24 0C lea edx, [esp+14Ch+seedBuff]
.text:100183B0 50 push eax
.text:100183B1 51 push ecx
.text:100183B2 8D 5E 02 lea ebx, [esi+2]
.text:100183B5 68 58 17 03 10 push offset aXX ; "%x %x "
.text:100183BA C6 06 2D mov byte ptr [esi], '-' ; msg[0] = '-'
.text:100183BD 52 push edx
.text:100183BE E8 D0 6B 00 00 call sprintf
.text:100183C3 8D 4C 24 1C lea ecx, [esp+15Ch+seedBuff]
.text:100183C7 83 C4 10 add esp, 10h
.text:100183CA 53 push ebx
.text:100183CB 68 91 00 00 00 push 91h
.text:100183D0 51 push ecx
.text:100183D1 E8 9A 00 00 00 call repeat_str ; repeatedly copy the seed string over the msg
.text:100183D6 83 C4 0C add esp, 0Ch
.text:100183D9 A1 3C 15 03 10 mov eax, lgcopyright
.text:100183DE 53 push ebx
.text:100183DF 68 91 00 00 00 push 91h
.text:100183E4 50 push eax
.text:100183E5 E8 86 00 00 00 call repeat_str ; xor the copyright over the string
.text:100183EA 8D 84 24 C4 00 00 00 lea eax, [esp+158h+keys]
.text:100183F1 83 C4 0C add esp, 0Ch
.text:100183F4 68 67 F7 42 92 push 9242F767h ; FREE_SEED_2^VENDOR_KEY5
.text:100183F9 68 ED B8 40 F6 push 0F640B8EDh ; FREE_SEED_1^VENDOR_KEY5
.text:100183FE 68 50 17 03 10 push offset aXX_0 ; "%x%x"
.text:10018403 50 push eax
.text:10018404 E8 8A 6B 00 00 call sprintf
.text:10018409 8D BC 24 C8 00 00 00 lea edi, [esp+15Ch+keys]
.text:10018410 83 C4 10 add esp, 10h
.text:10018413 B9 FF FF FF FF mov ecx, 0FFFFFFFFh
.text:10018418 2B C0 sub eax, eax
.text:1001841A F2 AE repne scasb ; ecx = strlen(keys) ???
.text:1001841C 8D 84 24 B8 00 00 00 lea eax, [esp+14Ch+keys]
.text:10018423 53 push ebx
.text:10018424 68 91 00 00 00 push 91h
.text:10018429 50 push eax
.text:1001842A E8 41 00 00 00 call repeat_str ; reverse the result
.text:1001842F 83 C4 0C add esp, 0Ch
.text:10018432 B8 02 00 00 00 mov eax, 2 ; eax = MSG_DATA
.text:10018437 BA 92 00 00 00 mov edx, 92h ; edx = LM_MSG_LEN-1
.text:1001843C
.text:1001843C reverseResult: ; CODE XREF: lg_encrypt+C8j
.text:1001843C 8A 0C 30 mov cl, [eax+esi] ; cl = msg[eax]
.text:1001843F 40 inc eax
.text:10018440 88 4C 14 24 mov [esp+edx+14Ch+str], cl ; str[edx] = cl
.text:10018444 4A dec edx
.text:10018445 83 FA 02 cmp edx, 2
.text:10018448 7D F2 jge short reverseResult
.text:1001844A 8D 74 24 26 lea esi, [esp+26h] ; esi = str[MSG_DATA]
.text:1001844E 8B FB mov edi, ebx ; edi = msg[MSG_DATA]
.text:10018450 B9 24 00 00 00 mov ecx, 24h
.text:10018455 F3 A5 rep movsd ; memcpy(&msg[2], &str[2], (24h*4+1))
.text:10018457 A4 movsb
.text:10018458 5F pop edi
.text:10018459 5E pop esi
.text:1001845A 5B pop ebx
.text:1001845B 81 C4 40 01 00 00 add esp, 140h
.text:10018461 C3 retn
.text:10018461 lg_encrypt endp


gerbay
March 31st, 2007, 20:24
I prepared a document about FlexLM 5.0 license cracking..

it is very easy..

FoxB
April 1st, 2007, 00:57
Quote:
[Originally Posted by gerbay;64738]I prepared a document about FlexLM 5.0 license cracking..

it is very easy..


Old info.
Way from 5.x to 10.8.x (and 11 beta) is very long. imxo.

gerbay
April 1st, 2007, 05:29
Quote:
[Originally Posted by FoxB;64741]Old info.
Way from 5.x to 10.8.x (and 11 beta) is very long. imxo.


NoLOcKs needs this information and I prepared a document for the user NoLOcKs..

Also I cracked flexlm 5.x, 6.x, 7.x, 9.x and 10.8..

< Improper Request Removed.>

NoLOcKs
April 1st, 2007, 10:47
10x gerbay

you helped me much !

If to need something, pls tell me !

bye

NoLOcKs

RCER
January 18th, 2008, 11:02
Quote:
[Originally Posted by gerbay;64746]NoLOcKs needs this information and I prepared a document for the user NoLOcKs..

Also I cracked flexlm 5.x, 6.x, 7.x, 9.x and 10.8..

< Improper Request Removed.>


Hi Gerbay,

intouch crack.pdf is very well written and good to follow even for a beginning reverser like me. the only thing I don't understand is how did you know that the address from lc_init is base+0x00D850 ?

Also, do you have any tutors from your 7.x, 9.x and 10.8 flex reversing?

gerbay
January 18th, 2008, 15:41
Hi RCER
You can use IDA (Interactive Disassembler) and flexlm flirt signature for finding methods easily. Other way; I wrote an IDA plugin (comes with source code, you can find in this forum). You can use my IDA plugin and you can load coff object file or coff library to IDA database, It identifies possible method signatures..

I didn't write any other tutors about flexlm, but you can read "CrackZ" tutorials about flexlm.. They are good tutorials about flexlm cracking and you can find flexlm 9.2 source code. I think, inspecting source code is a good idea for understanding flexlm license system..

RCER
January 19th, 2008, 01:32
Hi Gerbay,

Thanks a lot and I will follow your advice

Regards

RCER

roli_bark
January 19th, 2008, 03:56
Here's a VERY good paper on reversing FLEXlm (up until v9.2).
The BEST artcile I found in the NET so far ...
Njoy ...

RCER
January 19th, 2008, 05:08
Roli_bark

Thanks a lot for the tutorial.


Regards

RCER

RCER
January 23rd, 2008, 09:32
Quote:
[Originally Posted by roli_bark;71948]Here's a VERY good paper on reversing FLEXlm (up until v9.2).
The BEST artcile I found in the NET so far ...
Njoy ...


Hi roli_bark,

I have read the tutorial several times, and am able to follow the red line. However due to the fact that I am a rev engineering rooky, and not familiar with C, I will need to do a lot more reading before I will grasp everything.
Anyway it is fun to try to learn something new.
One of the things I have been trying to figure out is how to calculate idx in the below code. I do understand the syntax, but it is unclear to me where the value V = 86 is coming from. I now this is a pointer, but I don't know where to find it

Maybe you can help me.

thanks

Observe that cmath.exe calls lc_new_job(), which in turn calls lc_init(), for vendor & job initialization but
lmcrypt.exe calls lc_init() directly because vendor keys, seeds and name are already included in lmcrypt.exe
(put together in vendor structure by macros) so it only needs to initialize job. In both processes there are two calls
to l_string_key() and in both situations the first one returns 21D5B6E8572E, the insignificant number for
oldkey(), and only the second call matters. The two processes calls l_string_key() in slightly different ways,
basically checkout needs to provide user license key for checksum comparison but keygen doesn’t need that input.
However the part for calculating the true hash are the same.
int idx = (*job->vendor) % XOR_SEEDS_ARRAY_SIZ; /* idx = V % 20 = 86 % 20 = 6 */

utuh_garubuk
April 28th, 2008, 04:36
Quote:
[Originally Posted by gerbay;64738]I prepared a document about FlexLM 5.0 license cracking..

it is very easy..



Thanks gerbay that is very good tutorial. btw..I have question, what's different "HOSTID=ANY" and "HOSTID=WONDERWARE_HWKEYID=xxxxx"..? I successfully build license for "HOSTID=ANY", but the license can not use when I try to build for dongle ("HOSTID=WONDERWARE_HWKEYID=xxxxx" ,I used same lmcrypt as your explain in tutorial. can you help me..
Thanks.

FoxB
April 28th, 2008, 09:11
you can upload daemon's file?

zqi.liu
August 5th, 2009, 20:14
hi utuh_garubuk,
I have the same question, Did you get the answer for that? please tell me thanks


MSN:zqi.liu@hotmail.com

disavowed
August 6th, 2009, 20:26
utuh_garubuk hasn't been online in about 1.5 years. good luck getting a response from him