Dongle protection reversing (HASP) - Pinit dongle testing
(Encyclopaedia Universalis: the French reference)
project3

by The+Chineese

+cracker

(29 November 1997)


Courtesy of reverser's page of reverse engineering
Well, another interesting dongle essay... pinit tests and dongle verifications programmed in visual basic... gosh! There is may be a little too much code in here, but people that have to tackle dongles will appreciate this essay a lot.

Let hundred archive sites blossom!
Another important lesson (once more): As +ORC always teached, to know the HISTORY OF SOFTWARE is of paramount importance for our cracking endeavours... As many of you will probably know, in every decent virus group there is at least one guy that has the title (and function) of "keeper of the virii"... a very useful 'sofware' sort of archivist, that collects and keeps available past (rare) specimens for all interested researchers...
Crackers should in my opinion begin to find (or nominate :-) some 'keepers of the old targets'... people who have somewhere very stable shell space and could gather, maintain, explain, update and keep available for everybody (of course uncracked :-) for instance, the WHOLE collection of all PAST versions of Hexedit.
Let hundred archive sites blossom... I bet, moreover, that such "specialized" archive-sites would have MANY more visitors (and for ever!) that many poor cracking/hacking "banal" pages have at the moment!
This said here you have The+Chineese cracking 'the evolution' of a French dongle protected encyclopedia... head his words: you don't need a dongle to crack a dongle protection! This is true, remember, for MOST DONGLE PROTECTIONS! Yes, my readers, I actually don't know why +ORC speaks in his tut of hardware dongle cracking... in my own experience I have seen that you can crack (almost) all dongles without hardware... and without even having put your hands on the dongle itself! (So much for "heavy hardware protection enjoy!

DONGLE PROTECTION (HASP)
ENCYCLOPAEDIA UNIVERSALIS
(the french Reference of Encyclopaedia)

ENCYCLOPAEDIA UNIVERSALIS SAGA
---------------------------------

Let's study the History of they Protection Scheme.
(as +ORC wrote it's important to study the History of
software Protection scheme)
look at  http://www.encyclopaedia-universalis.fr
there is no downloadable Version but some Friend told
me that for the UNIVERSALIS Version 3 (1997) the latest one,
they (Universalis Crew) make a "Marketing" offer:
they send you the Complete Version 3 (with the Dongle of Course)
and you try it for 15 Days.
If your are not satisfied you send them back the Dongle and CD-Rom !
(and don't forget to thanks them with a 'Merci Beaucoup')


UNIVERSALIS 1 (1995):
------------------------

(16 bit writen in VBasic and BC++ (VBRUN300.dll and use Hasp.386))

dongle Type: i don't know (HASP! BUT WHICH ONE ??)

the target : EU.DLL 103.424 Bits (16Bit writen in BC++) 

the Weakness:

after launching the proggy 
(cdu.exe (32000 Color) or cdul.exe (256 colors)
there is a messagebox (16bit) who tell you in a bad french

"Aucun serveur protection actif n'a pu etre trouve (IPX ou NETBIOS)"

the Difficulties: 

the EU.DLL is moveable, it's not easy to put a breakpoint with S-ice
EU.DLL is called by VBRUN300.DLL




UNIVERSALIS 2 (1996):( addons : ATLAS , PHONETISEUR)
------------------------------------------------------

(16 bit writen in VBasic (VBRUN300.dll and use Hasp.vxd))

dongle Type : MEMOHASP 1 ((according the dongle it-self)

the target : EU.DLL 120.784 Bits (16bt writen in BC++)

the Weakness:
same as above with the error message: "La clé de protection est absente"

the Difficulties:

same a above and a Checksum on EU.DLL
and some other call to Error Routine



UNIVERSALIS 3 (1997): ( addons : ATLAS , PHONETISEUR, DICTIONNARY, PAINTING )
------------------------------------------------------------------------------

(pseudo 32bit bit writen in VBasic (VBRUN300.dll and use Hasp.vxd))

Dongle Type: HASP 3 (according the dongle it-self)

the target : EU.DLL 127.344 Bits (16bt writen in C++)

the Weakness: no more Messagebox (but we use kernel!openfile)

the Difficulties:

a little bit more difficult
cause in the previous version the proggy starts the interface an
via a messagebox tell us "erreur pas de dongle".
in this one it does nothing it just Crash .
( allways a Checksum on EU.DLL and some other call to Error Routine )





TOOLS:
-------------

	-S-ice 3.21
	-WDasm8.9 (or previous)
	-Hworks32 (any Editor)
	and ultraedit32 for writing this essay :-)

INTRODUCTION --------------- as Reverser+ said Dongle protection is the "bête noire" of all Crackers, and i thanx him for the DONGLE PROJECT and Zafernon for his works on Hasp. but This one is not so difficult !. A) let's study UNIVERSALIS VERSION 1 (95): ------------------------------------------- in the Universalis Case using bpio (-h) 378 (379/379 etc) doesnt Works and if we look at the dea-listing of EU.DLL we found suspicious function like PINIT, PTEST etc.. Disassembly of File: Eu.dll +++++++++++++++++++ SEGMENT INFO ++++++++++++++++++++++++ Number of Code/Data Segments = 15 ... +++++++++++++++++++ MENU INFORMATION ++++++++++++++++++ There Are No Menu Resources in This Application +++++++++++++++++ DIALOG INFORMATION ++++++++++++++++++ There Are No Dialog Resources in This Application +++++++++++++++++++ IMPORTED FUNCTIONS ++++++++++++++++++ Number of Imported Modules = 6 (decimal) Import Module 001: GDI Import Module 002: KERNEL Import Module 003: TOOLHELP Import Module 004: USER Import Module 005: WIN87EM Import Module 006: MVCL13W +++++++++++++++++++ ENTRY TABLE FUNCTIONS ++++++++++++++++++ Number of Entry Table Functions = 0055 (decimal) Addr:0006.00C2 Ord:0001d Type:FFh Name: EU_INIT {Exported} Addr:0006.01B2 Ord:0002d Type:FFh Name: EU_CLOSE {Exported} Addr:0006.0050 Ord:0003d Type:FFh Name: EU_ERROR {Exported} ... ... ... Addr:0010.01C2 Ord:0051d Type:FFh Name: CVTANSI2EU {Exported} Addr:0014.0256 Ord:0060d Type:FFh Name: PINIT {Exported} <-- in fact PINIT (PTEST, PCLOSE) Addr:0014.0341 Ord:0061d Type:FFh Name: PTEST {Exported} <-- i.e Port(INIT) or Printer(INIT) .. Addr:0014.0318 Ord:0062d Type:FFh Name: PCLOSE {Exported} <-- are called for DONGLE CHECKING Addr:0000.0000 Ord:0107d Type:00h Name: DLL pour Encyclopaedia Universalis (c) W.P. Dauchy 1995 Addr:0000.0000 Ord:0163d Type:00h Name: EU as you can see this dll is moveable so it's hard to bpx at this Function ! so it's easier to use bpx messagebox then fire cdul.exe(or cdu.exe) and you 'll break at messagebox and after two F12 in Sice you stand here (at 0014.39d ) in PTEST (in fact PTEST is called very often (in Background) and is TESTING if you have not removed the Dongle ) Exported fn(): PTEST - Ord:003Dh :0014.0341 B8FFFF mov ax, SEG ADDR of Segment 0015 :0014.0344 45 inc bp :0014.0345 55 push bp :0014.0346 8BEC mov bp, sp :0014.0348 1E push ds :0014.0349 8ED8 mov ds, ax :0014.034B B80200 mov ax, 0002 :0014.034E 9AFFFF0000 call 0001.2D00h :0014.0353 56 push si :0014.0354 57 push di :0014.0355 C746FC0000 mov word ptr [bp-04], 0000 :0014.035A A0631A mov al, [1A63] :0014.035D 98 cbw :0014.035E 0BC0 or ax, ax <-- we change it into xor ax,ax (33c0) :0014.0360 740C je 036E to force the jmp :0014.0362 3D0100 cmp ax, 0001 :0014.0365 7417 je 037E :0014.0367 3D0200 cmp ax, 0002 :0014.036A 7423 je 038F :0014.036C EB3B jmp 03A9 :0014.036E 833E641A00 cmp word ptr [1A64], 0000 <-- flag to 0 = GOOD GUY :0014.0373 7509 jne 037E <-- 2 nop (9090) :0014.0375 0E push cs <-- 1 nop (90) :0014.0376 E88DFE call 0206 <-call for checking dongle change into xor ax,ax/nop :0014.0379 A3641A mov [1A64], ax (i.e 33c090) :0014.037C EB2B jmp 03A9 :0014.037E 833E641A00 cmp word ptr [1A64], 0000 :0014.0383 750A jne 038F :0014.0385 90 nop :0014.0386 0E push cs :0014.0387 E86501 call 04EF :0014.038A A3641A mov [1A64], ax :0014.038D EB1A jmp 03A9 :0014.038F 833E641A00 cmp word ptr [1A64], 0000 :0014.0394 7407 je 039D :0014.0396 6A00 push 0000 :0014.0398 90 nop :0014.0399 0E push cs :0014.039A E82700 call 03C4 <-- call PERROR (which call the Messagebox) :0014.039D A1641A mov ax, [1A64] <-- after 2 p-ret(F12) on messagebox we stand here :0014.03A0 8946FC mov [bp-04], ax :0014.03A3 C706641A0000 mov word ptr [1A64], 0000 :0014.03A9 A0631A mov al, [1A63] :0014.03AC 98 cbw :0014.03AD 40 inc ax :0014.03AE BB0300 mov bx, 0003 :0014.03B1 99 cwd :0014.03B2 F7FB idiv bx :0014.03B4 8816631A mov [1A63], dl :0014.03B8 8B46FC mov ax, [bp-04] :0014.03BB 5F pop di :0014.03BC 5E pop si :0014.03BD 8D66FE lea sp, [bp-02] :0014.03C0 1F pop ds :0014.03C1 5D pop bp :0014.03C2 4D dec bp :0014.03C3 CB retf Exported fn(): PERROR - Ord:0027h :0014.03C4 B8FFFF mov ax, SEG ADDR of Segment 0015 :0014.03C7 45 inc bp :0014.03C8 55 push bp :0014.03C9 8BEC mov bp, sp :0014.03CB 1E push ds :0014.03CC 8ED8 mov ds, ax :0014.03CE B81401 mov ax, 0114 :0014.03D1 9AFFFF0000 call 0001.2D00h :0014.03D6 56 push si :0014.03D7 57 push di :0014.03D8 837E0600 cmp word ptr [bp+06], 0000 :0014.03DC 7506 jne 03E4 :0014.03DE A1641A mov ax, [1A64] :0014.03E1 894606 mov [bp+06], ax :0014.03E4 837E0600 cmp word ptr [bp+06], 0000 :0014.03E8 750D jne 03F7 :0014.03EA 33C0 xor ax, ax :0014.03EC 5F pop di :0014.03ED 5E pop si :0014.03EE 8D66FE lea sp, [bp-02] :0014.03F1 1F pop ds :0014.03F2 5D pop bp :0014.03F3 4D dec bp :0014.03F4 CA0200 retf 0002 ...... ...... ...... So if we make the change the code at 0014.35e and 0014.36e we defeat the Dongle Test But we notice that if there is no more messagebox warning us about "pas de Dongle" the proggy doesnt works at all cause the search index is not initialised. in fact We forgot the PINIT function ! (The PINIT function Test the Dongle and if there is one it make the search index initialisation) so bpx messagebox fire the proggy (cdu.exe or cdul.exe) and when you break into Messagox do 3 F12 and you stand in VBRUN300.DLL in a call Far Routine in fact you are in the routine who call all the PINIT, PTEST function of EU.DLL see this piece of code in VBRUN300.DLL 2277:6488 call Far es:[bx] <-- Now we can bpx at this adress call 6522 call 67D1 mov cl,FF Add di,di jmp cs:[DI+6498] . . . and in here we bpx 2277:6488 at the call Far es:[bx] we quit universalis and one more time we launch cdu.exe and we Break into vbrun300.dll at 2277:6488 do F8 and we are at the begining of the PINIT function in EU.DLL Exported fn(): PINIT - Ord:003Ch :0014.0256 B8FFFF mov ax, SEG ADDR of Segment 0015 <-- HERE :0014.0259 45 inc bp :0014.025A 55 push bp :0014.025B 8BEC mov bp, sp :0014.025D 1E push ds :0014.025E 8ED8 mov ds, ax :0014.0260 B80200 mov ax, 0002 :0014.0263 9AFFFF0000 call 0001.2D00h :0014.0268 56 push si :0014.0269 57 push di :0014.026A 6A0A push 000A :0014.026C 6A00 push 0000 :0014.026E 1E push ds :0014.026F 68621A push 1A62 :0014.0272 9AFFFF0000 call 0001.0F44h :0014.0277 83C408 add sp, 0008 :0014.027A 0E push cs :0014.027B E8F8FD call 0076 :0014.027E 8946FC mov [bp-04], ax :0014.0281 837EFC00 cmp word ptr [bp-04], 0000 :0014.0285 7403 je 028A <-- NOP NOP (9090) :0014.0287 E97F00 jmp 0309 and we pass the Dongle init and jmp to OK :0014.028A C606621A01 mov byte ptr [1A62], 01 :0014.028F 90 nop :0014.0290 0E push cs :0014.0291 E8BD01 call 0451 :0014.0294 68FFFF push SEG ADDR of Segment 0014 :0014.0297 68FFFF push WORD_VALUE_AT_ADDRESS 0014.009Eh :0014.029A 0E push cs :0014.029B E862FD call 0000 <---- testing the Dongle :0014.029E 83C404 add sp, 0004 :0014.02A1 8946FC mov [bp-04], ax :0014.02A4 837EFC00 cmp word ptr [bp-04], 0000 :0014.02A8 7510 jne 02BA :0014.02AA 68FFFF push SEG ADDR of Segment 0014 :0014.02AD 68FFFF push WORD_VALUE_AT_ADDRESS 0014.00E0h :0014.02B0 0E push cs :0014.02B1 E84CFD call 0000 <---- testing the Dongle :0014.02B4 83C404 add sp, 0004 :0014.02B7 8946FC mov [bp-04], ax :0014.02BA 837EFC00 cmp word ptr [bp-04], 0000 :0014.02BE 7433 je 02F3 :0014.02C0 C606621A02 mov byte ptr [1A62], 02 :0014.02C5 90 nop :0014.02C6 0E push cs :0014.02C7 E88701 call 0451 :0014.02CA 68FFFF push SEG ADDR of Segment 0014 :0014.02CD 68FFFF push WORD_VALUE_AT_ADDRESS 0014.01B0h :0014.02D0 0E push cs :0014.02D1 E82CFD call 0000 <--- testing the Dongle :0014.02D4 83C404 add sp, 0004 :0014.02D7 8BD0 mov dx, ax :0014.02D9 0BD2 or dx, dx :0014.02DB 7507 jne 02E4 :0014.02DD C746FC0000 mov word ptr [bp-04], 0000 :0014.02E2 EB0F jmp 02F3 :0014.02E4 817EFC8503 cmp word ptr [bp-04], 0385 :0014.02E9 7508 jne 02F3 :0014.02EB 83FA0B cmp dx, 000B :0014.02EE 7403 je 02F3 :0014.02F0 8956FC mov [bp-04], dx :0014.02F3 837EFC00 cmp word ptr [bp-04], 0000 :0014.02F7 7510 jne 0309 :0014.02F9 68FFFF push SEG ADDR of Segment 0014 :0014.02FC 68FFFF push WORD_VALUE_AT_ADDRESS 0014.013Ah :0014.02FF 0E push cs :0014.0300 E8FDFC call 0000 :0014.0303 83C404 add sp, 0004 :0014.0306 8946FC mov [bp-04], ax :0014.0309 8B46FC mov ax, [bp-04] :0014.030C A3641A mov [1A64], ax :0014.030F 5F pop di :0014.0310 5E pop si :0014.0311 8D66FE lea sp, [bp-02] :0014.0314 1F pop ds :0014.0315 5D pop bp :0014.0316 4D dec bp :0014.0317 CB retf just use an editor and change the Code the end For universalis 1 (1995) B) let's Study UNIVERSALIS VERSION 2 (96) ------------------------------------------------ looking at the header of the Dead-listing of EU.DLL we found More Suspicious Function (PREADWORD, PINIT , PTEST , _lread,_lclose,openfile etc ...) (humm!! a Checksum !! do you feel it ?) Addr:0003.00B5 Ord:0001d Type:FFh Name: EU_INIT {Exported} Addr:0003.0209 Ord:0002d Type:FFh Name: EU_CLOSE {Exported} Addr:0003.004C Ord:0003d Type:FFh Name: EU_ERROR {Exported} Addr:0001.00B4 Ord:0004d Type:FFh Name: WEP {Exported} Addr:0002.0000 Ord:0005d Type:FFh Name: LC_LOAD {Exported} Addr:0002.035E Ord:0006d Type:FFh Name: LC_UNLOAD {Exporte Addr:0004.09BB Ord:0037d Type:FFh Name: CVTEU2MAC {Exported} ... Addr:0006.0478 Ord:0038d Type:FFh Name: PERROR {Exported} Addr:0006.053B Ord:0039d Type:FFh Name: PREADWORD {Exported} <-- a new one ! ... Addr:0006.0772 Ord:0049d Type:FFh Name: PPARSEEXPR {Exported} Addr:0006.01D1 Ord:0060d Type:FFh Name: PINIT {Exported} <-- old functions Addr:0006.03CE Ord:0061d Type:FFh Name: PTEST {Exported} Addr:0006.036C Ord:0062d Type:FFh Name: PCLOSE {Exported} ... Addr:0000.0000 Ord:0115d Type:00h Name: DLL pour Encyclopaedia Universalis (c) W.P. Dauchy 1995 Addr:0000.0000 Ord:0171d Type:00h Name: EU and after searching the word HASP in the dead-listing we found this ... ... ... * Possible StringData Ref from Code Seg 001 ->"$HASP$CHECKSUM" <-- Well ! there is a checksum | Now we have a confirmation :0001.3DAB BEA525 mov si, 25A5 :0001.3DAE 1E push ds :0001.3DAF 8BFE mov di, si :0001.3DB1 8BF3 mov si, bx :0001.3DB3 B9FFFF mov cx, FFFF :0001.3DB6 F2 repnz :0001.3DB7 AE scasb :0001.3DB8 F7D1 not cx :0001.3DBA 2BF9 sub di, cx :0001.3DBC 87FE xchg si, di :0001.3DBE 1E push ds :0001.3DBF 06 push es :0001.3DC0 1F pop ds :0001.3DC1 07 pop es :0001.3DC2 D1E9 shr cx, 01 :0001.3DC4 F3 repz :0001.3DC5 A5 movsw :0001.3DC6 13C9 adc cx, cx :0001.3DC8 F3 repz :0001.3DC9 A4 movsb :0001.3DCA 1F pop ds * Possible StringData Ref from Code Seg 001 ->"$KEY$STAMP$" | :0001.3DCB BE9925 mov si, 2599 :0001.3DCE 8C5EEC mov [bp-14], ds :0001.3DD1 8976E8 mov [bp-18], si :0001.3DD4 8C5EEA mov [bp-16], ds :0001.3DD7 1E push ds :0001.3DD8 1E push ds :0001.3DD9 8BF3 mov si, bx ... ... What we know ?: -that the PINIT is call by VBUN300.DLL and if there is a dongle it initialise the Search Index. -that the PTEST is called very often and test if we not remove the dongle (if we have one) -and a messagebox warn us if we are Bad guys. -and there is a checksum this Version 2 (i dont explain here the checksum scheme because it's not the more important thing , we have just to remember how to recognize a checksum i.e looking for _lread, _lseek, openfile etc...) so looking at the PINIT function we found a call for openfile and getmodulefilename look at this Exported fn(): PINIT - Ord:003Ch :0006.01D1 B8FFFF mov ax, SEG ADDR of Segment 0007 :0006.01D4 45 inc bp :0006.01D5 55 push bp :0006.01D6 8BEC mov bp, sp :0006.01D8 1E push ds :0006.01D9 8ED8 mov ds, ax :0006.01DB 81EC9001 sub sp, 0190 :0006.01DF 56 push si :0006.01E0 57 push di :0006.01E1 EB14 jmp 01F7 :0006.01E3 00000000000000000000 BYTE 10 DUP(0) :0006.01ED 00000000000000000000 BYTE 10 DUP(0) :0006.01F7 FF364019 push word ptr [1940] :0006.01FB 16 push ss :0006.01FC 8D866EFE lea ax, [bp+FE6E] :0006.0200 50 push ax :0006.0201 680401 push 0104 :0006.0204 9AFFFF0000 call KERNEL.GETMODULEFILENAME <-- retrieve the EU.DLL name :0006.0209 16 push ss :0006.020A 8D866EFE lea ax, [bp+FE6E] :0006.020E 50 push ax :0006.020F 16 push ss :0006.0210 8D8672FF lea ax, [bp+FF72] :0006.0214 50 push ax :0006.0215 6A00 push 0000 :0006.0217 9AFFFF0000 call KERNEL.OPENFILE <-- open EU.DLL (green Light for the checksum) :0006.021C 8BF8 mov di, ax :0006.021E 0BFF or di, di :0006.0220 7D0E jge 0230 :0006.0222 B88C03 mov ax, 038C :0006.0225 5F pop di :0006.0226 5E pop si :0006.0227 8D66FE lea sp, [bp-02] :0006.022A 1F pop ds :0006.022B 5D pop bp :0006.022C 4D dec bp :0006.022D CB retf :0006.022E EB34 jmp 0264 :0006.0230 C646FB01 mov byte ptr [bp-05], 01 <-- for the Counter Checksum :0006.0234 EB10 jmp 0246 :0006.0236 57 push di :0006.0237 6A01 push 0001 :0006.0239 9AFFFF0000 call 0001.3D45h <-- this call for the mathematical Checksum and PREADWORD :0006.023E 83C404 add sp, 0004 <-- it crash if we change EU.DLL (we have to avoid it) :0006.0241 8BF0 mov si, ax :0006.0243 FE46FB inc byte ptr [bp-05] :0006.0246 807EFB03 cmp byte ptr [bp-05], 03 (3 time it call the Checksum Routine) :0006.024A 7CEA jl 0236 <--(change into NOP NOP (9090) ) to avoid the Checksum :0006.024C 57 push di :0006.024D 9AFFFF0000 call KERNEL._LCLOSE :0006.0252 0BF6 or si, si :0006.0254 740E je 0264 <-- force the jump (EB0E) :0006.0256 B88D03 mov ax, 038D :0006.0259 2BC6 sub ax, si :0006.025B 5F pop di :0006.025C 5E pop si :0006.025D 8D66FE lea sp, [bp-02] :0006.0260 1F pop ds :0006.0261 5D pop bp :0006.0262 4D dec bp :0006.0263 CB retf :0006.0264 9AFFFF0000 call 0001.0250h :0006.0269 6A0A push 000A :0006.026B 6A00 push 0000 :0006.026D 1E push ds :0006.026E 68541C push 1C54 :0006.0271 9AFFFF0000 call 0001.4F60h :0006.0276 83C408 add sp, 0008 :0006.0279 0E push cs :0006.027A E8CBFD call 0048 :0006.027D 8BF0 mov si, ax :0006.027F 0BF6 or si, si :0006.0281 7403 je 0286 <-- same as UNIV Version 1 NOP it (9090) :0006.0283 E9B300 jmp 0339 .... .... .... now what about PTEST ? lets see the code, it's the same as Version 1 Exported fn(): PTEST - Ord:003Dh :0006.03CE B8FFFF mov ax, SEG ADDR of Segment 0007 :0006.03D1 1E push ds :0006.03D2 8ED8 mov ds, ax :0006.03D4 56 push si :0006.03D5 33F6 xor si, si :0006.03D7 EB14 jmp 03ED :0006.03D9 00000000000000000000 BYTE 10 DUP(0) :0006.03E3 00000000000000000000 BYTE 10 DUP(0) :0006.03ED 9AFFFF0000 call 0001.031Fh :0006.03F2 3DFFFF cmp ax, FFFF :0006.03F5 7505 jne 03FC :0006.03F7 9AFFFF0000 call 0001.0250h :0006.03FC A0551C mov al, [1C55] :0006.03FF 98 cbw :0006.0400 0BC0 or ax, ax <-- change into xor ax,ax (33c0) :0006.0402 740C je 0410 to force the jump :0006.0404 3D0100 cmp ax, 0001 :0006.0407 7417 je 0420 :0006.0409 3D0200 cmp ax, 0002 :0006.040C 7423 je 0431 :0006.040E EB3B jmp 044B :0006.0410 833E561C00 cmp word ptr [1C56], 0000 <-- FLAGS if O goodguy :0006.0415 7509 jne 0420 <-- nop nop (9090) :0006.0417 0E push cs <-- nop :0006.0418 E86BFD call 0186 <--( test the Dongle ) xor ax,ax/nop :0006.041B A3561C mov [1C56], ax (i.e 33c090) :0006.041E EB2B jmp 044B :0006.0420 833E561C00 cmp word ptr [1C56], 0000 :0006.0425 750A jne 0431 :0006.0427 90 nop :0006.0428 0E push cs :0006.0429 E82A02 call 0656 :0006.042C A3561C mov [1C56], ax :0006.042F EB1A jmp 044B :0006.0431 833E561C00 cmp word ptr [1C56], 0000 :0006.0436 7407 je 043F :0006.0438 6A00 push 0000 :0006.043A 90 nop :0006.043B 0E push cs :0006.043C E83900 call 0478 <-- call to PERROR (Messagebox : "pas de clé de protection") :0006.043F 8B36561C mov si, [1C56] :0006.0443 C706561C0000 mov word ptr [1C56], 0000 :0006.0449 EB00 jmp 044B :0006.044B A0551C mov al, [1C55] :0006.044E 98 cbw :0006.044F 40 inc ax :0006.0450 BB0300 mov bx, 0003 :0006.0453 99 cwd :0006.0454 F7FB idiv bx :0006.0456 8816551C mov [1C55], dl :0006.045A EB14 jmp 0470 :0006.045C 00000000000000000000 BYTE 10 DUP(0) :0006.0466 00000000000000000000 BYTE 10 DUP(0) :0006.0470 8BC6 mov ax, si :0006.0472 5E pop si :0006.0473 1F pop ds :0006.0474 CB retf :0006.0475 5E pop si :0006.0476 1F pop ds :0006.0477 CB retf Exported fn(): PERROR - Ord:0026h :0006.0478 B8FFFF mov ax, SEG ADDR of Segment 0007 :0006.047B 45 inc bp :0006.047C 55 push bp :0006.047D 8BEC mov bp, sp :0006.047F 1E push ds :0006.0480 8ED8 mov ds, ax :0006.0482 81EC1401 sub sp, 0114 :0006.0486 56 push si :0006.0487 8B7606 mov si, [bp+06] :0006.048A 0BF6 or si, si :0006.048C 7504 jne 0492 :0006.048E 8B36561C mov si, [1C56] :0006.0492 0BF6 or si, si :0006.0494 750C jne 04A2 ... ... For the other call To PERROR when Clicking on item INTERNET/IMPRIMER/PANIER etc ... look at this piece of code :0006.08B2 B88B03 mov ax, 038B :0006.08B5 8BF8 mov di, ax :0006.08B7 EB14 jmp 08CD :0006.08B9 00000000000000000000 BYTE 10 DUP(0) :0006.08C3 00000000000000000000 BYTE 10 DUP(0) :0006.08CD 0BFF or di, di :0006.08CF 7408 je 08D9 <-- change into jmp 8d9 (EB08) :0006.08D1 57 push di for no more Error Message :0006.08D2 90 nop :0006.08D3 0E push cs :0006.08D4 E8A1FB call 0478 <-- call for PERROR :0006.08D7 EB02 jmp 08DB Messagebox "Logiciel Protege :0006.08D9 33C0 xor ax, ax :0006.08DB 5F pop di :0006.08DC 5E pop si :0006.08DD 8D66FE lea sp, [bp-02] :0006.08E0 1F pop ds :0006.08E1 5D pop bp :0006.08E2 4D dec bp :0006.08E3 CA0400 retf 0004 end of UNIVERSALIS 2. C) Let's work on UNIVERSALIS Version 3 (1997) ---------------------------------------------- The Protection scheme is Quasi The same as Version 2 the only change is that when launching cdu.exe (or cdul.exe) nothing happens (if no dongle is on printer port) it just crash. So if we ignore all the Precedent Work The Messagebox trick doesn Works ! So we can try bpx kernel!openfile ,cause we know that it's make a checksum with EU.DLL So do BPX KERNEL!OPENFILE and after some F5 in s-ice we are in EU.DLL at PINIT function . (and the Work is the same as Version 2) Exported fn(): PINIT - Ord:003Ch :0005.0207 B8FFFF mov ax, SEG ADDR of Segment 0008 :0005.020A 45 inc bp :0005.020B 55 push bp :0005.020C 8BEC mov bp, sp :0005.020E 1E push ds :0005.020F 8ED8 mov ds, ax :0005.0211 81EC8C01 sub sp, 018C :0005.0215 56 push si :0005.0216 57 push di :0005.0217 EB14 jmp 022D :0005.0219 00000000000000000000 BYTE 10 DUP(0) :0005.0223 00000000000000000000 BYTE 10 DUP(0) :0005.022D FF367619 push word ptr [1976] :0005.0231 16 push ss :0005.0232 8D8672FE lea ax, [bp+FE72] :0005.0236 50 push ax :0005.0237 68FF00 push 00FF :0005.023A 9AFFFF0000 call KERNEL.GETMODULEFILENAME :0005.023F 16 push ss :0005.0240 8D8672FE lea ax, [bp+FE72] :0005.0244 50 push ax :0005.0245 16 push ss :0005.0246 8D8672FF lea ax, [bp+FF72] :0005.024A 50 push ax :0005.024B 6A00 push 0000 :0005.024D 9AFFFF0000 call KERNEL.OPENFILE :0005.0252 8BF8 mov di, ax <-- we Break Here in sice after BPX OPENFILE :0005.0254 0BFF or di, di :0005.0256 7D0E jge 0266 :0005.0258 B88C03 mov ax, 038C :0005.025B 5F pop di :0005.025C 5E pop si :0005.025D 8D66FE lea sp, [bp-02] :0005.0260 1F pop ds :0005.0261 5D pop bp :0005.0262 4D dec bp :0005.0263 CB retf :0005.0264 EB34 jmp 029A :0005.0266 C646FB01 mov byte ptr [bp-05], 01 :0005.026A EB10 jmp 027C :0005.026C 57 push di :0005.026D 6A01 push 0001 :0005.026F 9AFFFF0000 call 0001.3D45h <-- Call for Checksum :0005.0274 83C404 add sp, 0004 :0005.0277 8BF0 mov si, ax :0005.0279 FE46FB inc byte ptr [bp-05] :0005.027C 807EFB03 cmp byte ptr [bp-05], 03 <-- 3 Time Checksum :0005.0280 7CEA jl 026C <--- NOP NOP (9090) :0005.0282 57 push di :0005.0283 9AFFFF0000 call KERNEL._LCLOSE :0005.0288 0BF6 or si, si :0005.028A 740E je 029A <-- Jmp 29a (EB0E) :0005.028C B88D03 mov ax, 038D :0005.028F 2BC6 sub ax, si :0005.0291 5F pop di :0005.0292 5E pop si :0005.0293 8D66FE lea sp, [bp-02] :0005.0296 1F pop ds :0005.0297 5D pop bp :0005.0298 4D dec bp :0005.0299 CB retf :0005.029A 6A0A push 000A :0005.029C 6A00 push 0000 :0005.029E 1E push ds :0005.029F 680A0A push 0A0A :0005.02A2 9AFFFF0000 call 0001.4F60h :0005.02A7 83C408 add sp, 0008 :0005.02AA 0E push cs :0005.02AB E89AFD call 0048 :0005.02AE 8BF0 mov si, ax :0005.02B0 0BF6 or si, si :0005.02B2 7403 je 02B7 <-- NOP NOP (9090) :0005.02B4 E90101 jmp 03B8 <-- jump to Good INITIALISATION :0005.02B7 C6060A0A00 mov byte ptr [0A0A], 00 :0005.02BC 90 nop :0005.02BD 0E push cs :0005.02BE E88203 call 0643 :0005.02C1 0E push cs :0005.02C2 E88BFD call 0050 :0005.02C5 0BC0 or ax, ax :0005.02C7 7412 je 02DB ... ... ... AND here The PTEST function (which is called very often (in background) " Dongle is still Present " ???) Exported fn(): PTEST - Ord:003Dh :0005.0443 B8FFFF mov ax, SEG ADDR of Segment 0008 :0005.0446 1E push ds :0005.0447 8ED8 mov ds, ax :0005.0449 56 push si :0005.044A 33F6 xor si, si :0005.044C 833E0C0AFF cmp word ptr [0A0C], FFFF :0005.0451 7506 jne 0459 :0005.0453 B88803 mov ax, 0388 :0005.0456 5E pop si :0005.0457 1F pop ds :0005.0458 CB retf :0005.0459 EB14 jmp 046F :0005.045B 00000000000000000000 BYTE 10 DUP(0) :0005.0465 00000000000000000000 BYTE 10 DUP(0) :0005.046F A00B0A mov al, [0A0B] :0005.0472 98 cbw :0005.0473 0BC0 or ax, ax <-- XOR AX,AX (33C0) :0005.0475 740C je 0483 Force the jump :0005.0477 3D0100 cmp ax, 0001 :0005.047A 7417 je 0493 :0005.047C 3D0200 cmp ax, 0002 :0005.047F 7423 je 04A4 :0005.0481 EB3B jmp 04BE :0005.0483 833E0C0A00 cmp word ptr [0A0C], 0000 :0005.0488 7509 jne 0493 <-- NOP NOP (9090) :0005.048A 0E push cs <-- NOP (90) :0005.048B E82EFD call 01BC it check the Dongle ( XOR AX,AX / NOP) :0005.048E A30C0A mov [0A0C], ax (i.e 33C090) :0005.0491 EB2B jmp 04BE :0005.0493 833E0C0A00 cmp word ptr [0A0C], 0000 :0005.0498 750A jne 04A4 :0005.049A 90 nop :0005.049B 0E push cs :0005.049C E83102 call 06D0 :0005.049F A30C0A mov [0A0C], ax :0005.04A2 EB1A jmp 04BE :0005.04A4 833E0C0A00 cmp word ptr [0A0C], 0000 :0005.04A9 7407 je 04B2 :0005.04AB 6A00 push 0000 :0005.04AD 90 nop :0005.04AE 0E push cs :0005.04AF E83900 call 04EB <--- call To PERROR messagebox "NO DONGLE" :0005.04B2 8B360C0A mov si, [0A0C] :0005.04B6 C7060C0A0000 mov word ptr [0A0C], 0000 :0005.04BC EB00 jmp 04BE :0005.04BE A00B0A mov al, [0A0B] :0005.04C1 98 cbw :0005.04C2 40 inc ax :0005.04C3 BB0300 mov bx, 0003 :0005.04C6 99 cwd :0005.04C7 F7FB idiv bx :0005.04C9 88160B0A mov [0A0B], dl :0005.04CD EB14 jmp 04E3 :0005.04CF 00000000000000000000 BYTE 10 DUP(0) :0005.04D9 00000000000000000000 BYTE 10 DUP(0) :0005.04E3 8BC6 mov ax, si :0005.04E5 5E pop si :0005.04E6 1F pop ds :0005.04E7 CB retf :0005.04E8 5E pop si :0005.04E9 1F pop ds :0005.04EA CB retf Exported fn(): PERROR - Ord:0026h :0005.04EB B8FFFF mov ax, SEG ADDR of Segment 0008 :0005.04EE 45 inc bp :0005.04EF 55 push bp :0005.04F0 8BEC mov bp, sp :0005.04F2 1E push ds :0005.04F3 8ED8 mov ds, ax :0005.04F5 81EC0001 sub sp, 0100 :0005.04F9 56 push si :0005.04FA 8B7606 mov si, [bp+06] :0005.04FD 0BF6 or si, si :0005.04FF 7504 jne 0505 :0005.0501 8B360C0A mov si, [0A0C] And Always the call To PERROR when Clicking on item INTERNET/IMPRIMER/PANIER etc ... :0007.0157 B88B03 mov ax, 038B :0007.015A 8BF8 mov di, ax :0007.015C EB14 jmp 0172 :0007.015E 00000000000000000000 BYTE 10 DUP(0) :0007.0168 00000000000000000000 BYTE 10 DUP(0) :0007.0172 0BFF or di, di :0007.0174 7408 je 017E <-- change into JMP 017E (EB08) :0007.0176 57 push di avoid the Message "logiciel protege contre le Piratage" :0007.0177 9AFFFF0000 call 0005.04EBh <-- call to PERROR :0007.017C EB02 jmp 0180 :0007.017E 33C0 xor ax, ax .... .... .... The End For UNIVERSALIS Version 3 -------------------- RESUME -------------------- Encyclopaedia Universalis is really a good and complete French Encyclopaedia. But The Protection Scheme is not really good (not at all)! Even if it use MEMOHASP Dongle ,its not a hard Crack, cause u dont need The Dongle To crack it at 100%! (c) REVERSED +Chineese (+HCU98) chineese@mygale.org
(c) The+Chineese All rights reversed
You are deep inside reverser's page of reverse engineering, choose your way out:

Back to project 3
redhomepage redlinks redanonymity +ORC redstudents' essays redacademy database
redtools redcocktails redantismut CGI-scripts redsearch_forms redmail_fravia
redIs reverse engineering legal?