New Method - MP serials/use of multiple procedure addresses

Share your advanced PureBasic knowledge/code with the community.
localmotion34
Enthusiast
Enthusiast
Posts: 665
Joined: Fri Sep 12, 2003 10:40 pm
Location: Tallahassee, Florida

New Method - MP serials/use of multiple procedure addresses

Post by localmotion34 »

So, expanding the use of multi-part serials can include the technique of using multiple verification procedures, all of which can do the same or different things.

THE KEY HERE IS TO MAKE SURE A DIFFERENT VERIFICATION PROCDURE IS CALLED EVERY TIME.

i will post my example at first, then followed by my source sode. i think last time it was too easy to figure out with the PB source right there. the source shows the clear method of how this was done, and can be implemented by even very basic users.

this uses multiple techniques to fight back at crackers, which will only delay the inevitable. HOWEVER, it SHOULD delay them enough for a developer to have a reasonable time to UPDATE, and keep things interesting.

http://www.penguinbyte.com/apps/pbwebst ... ection.zip

Code: Select all

!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
localmotion34
Enthusiast
Enthusiast
Posts: 665
Joined: Fri Sep 12, 2003 10:40 pm
Location: Tallahassee, Florida

Post by localmotion34 »

OK so its been a few days, and i take it no one has unpacked the EXE target, or couldnt patch ot keygen the app.

here is the basis of what i did:

1) Multipart serials: explained before

2) multiple and RANDOM procedure addresses that check the multipart serial


EX:

Code: Select all

sproc(0)=@checkotherserial()
sproc(1)=@checkotherserial1()
sproc(2)=@checkotherserial2()
sproc(3)=@checkotherserial3()
sproc(4)=@checkotherserial4()
See how there are 5 procedures that check the second part of the serial?

and to call one of them:

CallFunctionFast(sproc(Random(4)),userserial.s,username.s,useremail.s)

Now, the procedure that does the watermarking is handled the same way:

Code: Select all

proc(0)=@GetMeterImage()
proc(1)=@GetMeterImage1()
proc(2)=@GetMeterImage2()
proc(3)=@GetMeterImage3()
proc(4)=@GetMeterImage4()

Procedure GetMeterImage(id.l)
  *mr.Meter=GetWindowLong_(GadgetID(id),#GWL_USERDATA)
  bitmapreturn.l=*mr\PBimg
  Select CallFunctionFast(sproc(Random(4)),userserial.s,username.s,useremail.s)
    ;;we are now going to check the other serial part using RANDOM selection of a procedure address
    Case 1
      ProcedureReturn bitmapreturn 
    Case 0 ; hmmm, doesnt add up, so we will watermark the image 
      markedimage.l=CreateImage(#PB_Any,ImageWidth(*mr\PBimg),ImageHeight(*mr\PBimg))
      StartDrawing(ImageOutput(markedimage))
      DrawImage(ImageID(*mr\PBimg),0,0)
      DrawText(10,10,"##############",#Red,#Blue)
      StopDrawing()
      ProcedureReturn markedimage 
  EndSelect  
EndProcedure
and to call it:

SaveImage.l=CallFunctionFast(proc(Random(4)),themeter)

So, there are 5 procedures that do the image handling, each of which can call the checkotherserial() proedure array randomly.

5*5=25 permutations. Thats at least 50 jump patches.

3) Storing of serial check procedures in a DLL, as a "backup", and test the DLL MD5/CRC

Code: Select all

Procedure BadboyGetMeterImage(id.l) ; this procedure is here in case the DLL is modified.  BAD BOY!!
  ;;so you unpacked or patched the DLL huh?
  *mr.Meter=GetWindowLong_(GadgetID(id),#GWL_USERDATA)
  bitmapreturn.l=*mr\PBimg
  ;;hmmm, doesnt add up, so we will watermark the image 
  markedimage.l=CreateImage(#PB_Any,ImageWidth(*mr\PBimg),ImageHeight(*mr\PBimg))
  StartDrawing(ImageOutput(markedimage))
  DrawImage(ImageID(*mr\PBimg),0,0)
  DrawText(10,10,"##############",#Red,#Blue)
  StopDrawing()
  ProcedureReturn markedimage 
EndProcedure
;;; note that we have FIVE DIFFERENT procedures that check the second serial and return an image
;;; This array stores the address of those procedures which we can call AT RANDOM
proc(0)=@GetMeterImage()
proc(1)=@GetMeterImage1()
proc(2)=@GetMeterImage2()
proc(3)=@GetMeterImage3()
proc(4)=@GetMeterImage4()

Code: Select all

Procedure information(file.s, passedfingerprint.s)
  fingerprint.s=MD5FileFingerprint(file.s)
  If fingerprint=passedfingerprint
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf 
EndProcedure

;- check to see if security DLL is modified 
fprint.s=MD5FileFingerprint(curdir+"utility.dll")
If fprint="8251902aa5ecc4b8a9db158867fbb298"
  OpenLibrary(0,curdir+"utility.dll")
Else ;;well, well, someone modified the DLL.  now we set the procedure addresses to always watermark the image!!
  proc(0)=@BadboyGetMeterImage()
  proc(1)=@BadboyGetMeterImage()
  proc(2)=@BadboyGetMeterImage()
  proc(3)=@BadboyGetMeterImage()
  proc(4)=@BadboyGetMeterImage()
EndIf 
Notice that if the DLL is unpacked or inline patched, it is detected and the procedure array is changed to ALWAYS point to a procedure that returns a watermarked image. You can do the same from within the DLL to check the integrity of your EXE.

This is a scalable system, meaning that you can add more and more procedures to each array and increase the number of possible permutations. Hope this helps anyone that needs it. Ive spent a good deal of time reversing, and figured id share a way to make it a nightmare for crackers...

Source is here:

http://www.penguinbyte.com/apps/pbwebst ... ection.zip

Code: Select all

!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Nice work, thanks for posting, it's appreciated.
BERESHEIT
Post Reply