'---- Program: CLONE.BAS ' Demonstrate cloning data into .EXE's. Data is further ' protected via simple encryption technique and by checksum. DEFINT A-Z DECLARE FUNCTION Checksum% (TestString$) DECLARE FUNCTION CombineBytes% (HiByte%, LowByte%) DECLARE FUNCTION Cypher$ (dat$) DECLARE SUB CloneData (dat$, Program$) DECLARE FUNCTION GetClonedData$ (ProgName$, CloneErr%) DECLARE SUB HiLowBytes (IntValue%, HiByte%, LowByte%) DECLARE FUNCTION SearchEXE$ (ProgName$, Marker$) DECLARE SUB Uncypher (dat$) DIM SHARED BytesToData&, DataLen AS INTEGER '---- The copyright notice is for illustration purposes only. You ' are allowed to use/modify this code to suit your needs. -LS Copyright$ = "Copyright (C) 1990, Cobb Subscriber. All Rights Relaxed." CLS '---- Discover the checksum value then, REMark this line. 'PRINT Checksum%(Copyright$) '---- If a hacker has tampered with the copyright notice then END. ' Note: The value, 4657, was determined from the line above. IF NOT Checksum%(Copyright$) = 4657 THEN PRINT "The Copyright Notice is Altered - Program Terminated!" END END IF ProgName$ = "CLONE.EXE" YourName$ = GetClonedData$(ProgName$, CloneErr) IF LEN(YourName$) = 0 AND NOT CloneErr THEN PRINT "This Program Must Be Initialized With Your Name." INPUT "Please enter your name: ", YourName$ '---- Set length <= DataLen - 1 and terminate with a null. YourName$ = RTRIM$(LEFT$(YourName$, DataLen - 1)) + CHR$(0) CloneData YourName$, ProgName$ PRINT : PRINT "You Now Have Access Privilages." ELSEIF CloneErr THEN PRINT "The Program Data Area is Altered - Program Terminated!" END ELSE INPUT "Please enter your name: ", NameCheck$ IF LEN(NameCheck$) > 29 THEN NameCheck$ = LEFT$(NameCheck$, 29) IF NameCheck$ <> RTRIM$(YourName$) THEN PRINT "Unauthorized Access Denied! Program Terminated!" END ELSE PRINT "Welcome back, "; YourName$; "." END IF END IF FUNCTION Checksum% (TestString$) STATIC DEFINT A-Z test = 0 LoopCount = test FOR N = 1 TO LEN(TestString$) LoopCount = N IF N MOD 2 THEN HiByte = ASC(MID$(TestString$, N, 1)) ELSE GOSUB AddLowByte END IF NEXT '---- If the byte count is odd then we need to XOR IF LoopCount MOD 2 THEN GOSUB AddLowByte Checksum% = test EXIT FUNCTION AddLowByte: LowByte = ASC(MID$(TestString$, LoopCount, 1)) TwoBytes = CombineBytes(HiByte, LowByte) test = test XOR TwoBytes RETURN END FUNCTION SUB CloneData (dat$, Program$) DEFINT A-Z '---- Obtain a checksum value for dat$ string. checkS = Checksum%(dat$) '---- Break the checksum value into high and low bytes. HiLowBytes checkS, HiByte, LowByte '---- Convert High and Low Bytes into characters. CheckDat$ = CHR$(HiByte) + CHR$(LowByte) '---- Concatenate the strings for writing back to the EXE. temp$ = LEFT$(dat$ + STRING$(DataLen, 0), DataLen) + CheckDat$ temp$ = Cypher$(temp$) Handle = FREEFILE 'Get a number for the file. OPEN Program$ FOR BINARY AS #Handle PUT #Handle, BytesToData&, temp$ CLOSE #Handle END SUB FUNCTION CombineBytes% (HiByte%, LowByte%) STATIC DEFINT A-Z '---- Combine the two bytes into one, long integer. N& = (HiByte + 256&) + (LowByte * 256&) - 256 '---- Adjust integer's range to signed short integer range. IF N& > 32767 THEN N& = N& - 65536 CombineBytes% = N& END FUNCTION FUNCTION Cypher$ (dat$) DEFINT A-Z FOR N = 1 TO LEN(dat$) '---- Test the character so it doesn't go greater than 255 test = ASC(MID$(dat$, N, 1)) + 100 IF test > 255 THEN test = test - 100 '---- Build the cyphered string. temp$ = temp$ + CHR$(test) NEXT '---- Set the function with results. We don't alter dat$ Cypher$ = temp$ END FUNCTION FUNCTION GetClonedData$ (ProgName$, CloneErr%) DEFINT A-Z '---- Assign a token area big enough for marker, clone data ' and a stored checksum value. SpotForMarker$ = "–…û™12345678901234567890123456789012" TempMarker$ = LEFT$(SpotForMarker$, 4) CloneErr = 0 '---- Subtracting 4 bytes accounts for TempMarker$ DataLen = LEN(SpotForMarker$) - 4 '---- Search the EXE for the cloned data. dat$ = SearchEXE$(ProgName$, TempMarker$) Uncypher dat$ 'Uncypher the data. '---- If we have a null then the clone area contains data. Null = INSTR(dat$, CHR$(0)) IF Null THEN 'We have data! '---- What is the stored checksum value? HiByte = ASC(MID$(dat$, LEN(dat$) - 1)) LowByte = ASC(RIGHT$(dat$, 1)) Check = CombineBytes(HiByte, LowByte) '---- Compare the stored checksum to actual checksum. IF Check = Checksum%(LEFT$(dat$, INSTR(dat$, CHR$(0)))) THEN '---- Stored checksum matches actual checksum. GetClonedData$ = LEFT$(dat$, (Null - 1)) ELSE '---- A mad hacker has modified our cloned data. CloneErr = -1 GetClonedData$ = "" END IF ELSE 'We have no cloned data. GetClonedData$ = "" END IF '---- Subtracting 2 bytes accounts for checksum value. DataLen = DataLen - 2 END FUNCTION SUB HiLowBytes (IntValue%, HiByte%, LowByte%) STATIC DEFINT A-Z HiByte = IntValue AND &HFF LowByte = IntValue \ &HFF END SUB FUNCTION SearchEXE$ (ProgName$, Marker$) DEFINT A-Z Bytes = 16000 '16000 bytes to read with each pass. BytesToData& = 0 'Initialize it to zero. SeekPos& = 1 'Initialize to file's 1st byte. CountToMarker = 0 'The count to Marker$ location. Handle = FREEFILE 'Get a number for the file. OPEN ProgName$ FOR BINARY AS #Handle FiSize& = LOF(Handle) 'How big is the file? DO '---- 16000 bytes is to many so, reduce it. IF Bytes > FiSize& THEN Bytes = FiSize& '---- If SeekPos& + bytes is greater than FiSize&, reduce Bytes. IF Bytes + SeekPos& > FiSize& THEN Bytes = FiSize& - SeekPos& '---- Point into the file (SeekPos&) and input "Bytes". SEEK #Handle, SeekPos& A$ = INPUT$(Bytes, Handle) CountToMarker = INSTR(A$, Marker$) 'Is Marker in A$ ? IF CountToMarker THEN 'Yes, we found the Marker! '---- Calculate were the data is located. BytesToData& = SeekPos& + CountToMarker + LEN(Marker$) - 1 SEEK #Handle, BytesToData& 'Now get the data. SearchEXE$ = INPUT$(DataLen, Handle) CLOSE #Handle EXIT FUNCTION 'We're out of here! END IF '---- We've reached the end of the file and did not find ' our Marker$. This prevents an endless loop. IF Bytes + SeekPos& >= FiSize& THEN EXIT DO '---- We subtract the Marker length from our next SeekPos& ' in case it's 4 bytes were split during the last input. SeekPos& = Bytes + SeekPos& - LEN(Marker$) LOOP '---- The EXE has no Marker or, maybe, some hacker changed it. CLOSE #Handle PRINT "Error. Could not find Marker! Program Terminated!" END END FUNCTION SUB Uncypher (dat$) DEFINT A-Z FOR N = 1 TO LEN(dat$) '---- Test whether dat$ is original, un-cyphered SpotForMarker$ test = ASC(MID$(dat$, N, 1)) - 100 '---- If the character wasn't cyphered then don't uncypher it. IF test < 0 THEN temp$ = temp$ + CHR$(test + 100) ELSE temp$ = temp$ + CHR$(test) END IF NEXT SWAP dat$, temp$ END SUB