;
; Name		:	SMEG
; Description	:	XFD external slave to detect and remove SMEG viri
; Author	:	Zbigniew `Zeeball` Trzcionkowski
; Date		:	27.07.2001
; Version	:	2
; Supports	:	PENETRATOR (SMEG clone)
;                       SMEG2 (1556 bytes)
;                       SMEG2 (1604 bytes)
;
; In future	:	(more clones?)
; Disclaimer	:	The slave and this source are Public Domain.
; Comments	:	fixed hunk check to SMEG based :-)
;
; I TAKE NO RESPONSIBILITY FOR ANY DATALOSS CAUSED BY THIS SUBLIBRARY.
;
; USAGE: Use xfdDecrunch to clean whole directories.
;        I take no responisbility for this software,
;        and decrunched files that had to stay untouched :-)
;        This is xfdDecrunch not VirusZ!



	section	ZbL!,code
ZbL:
	moveq	#-1,d0		;security
	rts			;ender
	
	dc.b	"XFDF"		;XFDF_ID
	dc.w	1,0
	dc.l	0,0,Penetrator

	dc.b	"$VER: SMEG-CLONE 1 (12.07.01) by Zbigniew `Zeeball` Trzcionkowski",10,0


Smeg1Name:	dc.b	"[PENETRATOR! virus]",0
Smeg2Name:	dc.b	"[SMEG2 virus]",0	;typ B
Smeg3Name:	dc.b	"[SMEG2 virus]",0	;typ A
	even

Penetrator:
		dc.l	SMG2		;next slave
		dc.w	2		;version
		dc.w	38		;master version
		dc.l	Smeg1Name	;name
		dc.w	0		;XFDPFF_RELOC
		dc.w	0
		dc.l	RecogPEN	;recog buffer
		dc.l	RemPEN		;decrunch buffer
		dc.l	0		;recog segment
		dc.l	0		;decrunch segment
		dc.w	0,0		;slave/replace id
		dc.l	80		;min. file length for header and data

SMG2:		dc.l	SMG		;next slave
		dc.w	2		;version
		dc.w	38		;master version
		dc.l	Smeg2Name	;name
		dc.w	0		;XFDPFF_RELOC
		dc.w	0
		dc.l	RecogSMG2	;recog buffer
		dc.l	RemSMG2		;decrunch buffer
		dc.l	0		;recog segment
		dc.l	0		;decrunch segment
		dc.w	0,0		;slave/replace id
		dc.l	80		;min. file length for header and data

SMG:		dc.l	0		;next slave
		dc.w	2		;version
		dc.w	38		;master version
		dc.l	Smeg3Name	;name
		dc.w	0		;XFDPFF_RELOC
		dc.w	0
		dc.l	RecogSMG	;recog buffer
		dc.l	RemSMG		;decrunch buffer
		dc.l	0		;recog segment
		dc.l	0		;decrunch segment
		dc.w	0,0		;slave/replace id
		dc.l	80		;min. file length for header and data



PEN_size	=	6796

RecogPEN:
	movem.l	d2-d7/a0-a6,-(sp)
	bsr.b	.dupa
	movem.l	(sp)+,d2-d7/a0-a6
	rts
	
.Dupa:
	cmp.l	#$3f3,(a0)
	bne	.no

	move.l	8(a0),d0
	lsl.l	#2,d0

	lea.l	$14(a0,d0.l),a0

	cmp.w	#$3ea,2(a0)		; DATA
	beq.b	.okiej

	cmp.w	#$3e9,2(a0)		; CODE
	bne.b	.no

.okiej
	addq.l	#4,a0
	
	move.l	(a0)+,d0		;HUNKCODE len in longs

	add.l	d0,a0
	add.l	d0,a0
	add.l	d0,a0
	add.l	d0,a0

	sub.l	#PEN_size,a0

	cmp.l	#$4eaefd84,40(a0)
	bne.b	.no
	cmp.l	#$4eaeff88,44(a0)
	bne.b	.no
	cmp.w	#$610c,48(a0)
	bne.b	.no
	cmp.l	#$4eaeff82,50(a0)
	bne.b	.no
	cmp.l	#$4cdf7fff,54(a0)
	bne.b	.no

.Yes:
	moveq	#1,d0
	rts
.no:
	moveq	#0,d0
	rts




SMG_size2	=	1604

RecogSMG2:
	movem.l	d2-d7/a0-a6,-(sp)
	bsr.b	.dupa
	movem.l	(sp)+,d2-d7/a0-a6
	rts
	
.Dupa:
	cmp.l	#$3f3,(a0)
	bne	.no


	move.l	8(a0),d0
	lsl.l	#2,d0
	lea.l	$14(a0,d0.l),a0

	cmp.w	#$3ea,2(a0)		; DATA
	beq.b	.okiej

	cmp.w	#$3e9,2(a0)		; CODE
	bne.b	.no

.okiej
	addq.l	#4,a0

	move.l	(a0)+,d0		;HUNKCODE len in longs

	add.l	d0,a0
	add.l	d0,a0
	add.l	d0,a0
	add.l	d0,a0

	sub.l	#SMG_size2,a0

	cmp.l	#$4cdf7ffe,108(a0)
	bne.b	.no
	cmp.l	#$4a804e75,112(a0)
	bne.b	.no
	cmp.l	#$534d4700,116(a0)
	bne.b	.no

.Yes:
	moveq	#1,d0
	rts
.no:
	moveq	#0,d0
	rts


SMG_size	=	1556

RecogSMG:
	movem.l	d2-d7/a0-a6,-(sp)
	bsr.b	.dupa
	movem.l	(sp)+,d2-d7/a0-a6
	rts

.Dupa:
	cmp.l	#$3f3,(a0)
	bne	.no

	move.l	8(a0),d0
	lsl.l	#2,d0
	lea.l	$14(a0,d0.l),a0

	cmp.w	#$3ea,2(a0)		; DATA
	beq.b	.okiej

	cmp.w	#$3e9,2(a0)		; CODE
	bne.b	.no

.okiej
	addq.l	#4,a0

	
	move.l	(a0)+,d0		;HUNKCODE len in longs

	add.l	d0,a0
	add.l	d0,a0
	add.l	d0,a0
	add.l	d0,a0

	sub.l	#SMG_size,a0

	cmp.l	#$4eaefd54,84(a0)
	bne.b	.no
	
	cmp.l	#$4cdf7ffe,88(a0)
	bne.b	.no
	
	cmp.l	#$4a804e75,92(a0)
	bne.b	.no

	cmp.l	#$611067e4,96(a0)
	bne.b	.no

.Yes:
	moveq	#1,d0
	rts
.no:
	moveq	#0,d0
	rts



;--------------------------------------------------------------------
;--------------------------------------------------------------------
RemPEN:
	movem.l	d2-d7/a0-a6,-(sp)

	moveq	#0,d0

	move.l	4(a0),d7		; xfdbi_SourceBufLen


	movem.l	d0-a6,-(sp)
	move.l	a0,a6
	move.l	0(a0),a0		; xfdbi_SourceBuffer


	move.l	8(a0),d0
	lsl.l	#2,d0
	lea.l	$14(a0,d0.l),a0

	cmp.w	#$3ea,2(a0)		; DATA
	beq.b	.okiej

	cmp.w	#$3e9,2(a0)		; CODE
	beq.b	.okiej

	movem.l	(sp)+,d0-a6
	bra.w	.cant

.okiej:
	addq.l	#4,a0


	move.l	a0,a5			; begin of codehunk

	;****** CORRECT HUNKLENGTHs...

	move.l	0(a6),a0		; xfdbi_SourceBuffer
	lea.l	$14(a0),a0
	sub.l	#PEN_size/4,(a0)
	sub.l	#PEN_size/4,(a5)

	;****** REPLACE STOLEN INSTRUCTION...

	move.l	#$61000002,d1

	move.l	a5,a0
	add.l	(a5),a0
	add.l	(a5),a0
	add.l	(a5),a0
	add.l	(a5),a0

	move.l	#$4eae0000,d4
	move.w	64(a0),d4	

	move.l	a5,a2			; BeginOfCodeHunk

.restore
	move.l	(a0),d2
	cmp.l	d1,d2
	bne	.none
	
	move.l	d4,(a0)			; restore JSR XXX(a6)

.none
	addq.l	#2,d1
	subq.l	#2,a0
	cmpa.l	a0,a2
	bne	.restore

	;****** MAKE CLEAN COPY...


	move.l	4(a6),a2		; xfdbi_SourceBufLen
	sub.l	#PEN_size,a2
	add.l	0(a6),a2		; xfdbi_SourceBuffer

	move.l	a5,a0			; before
	move.l	(a5),d0
	lsl.l	#2,d0
	add.l	d0,a0
	lea.l	PEN_size(a0),a1	; after
	addq.l	#4,a1
	addq.l	#4,a0

.copy:
	move.l	(a1)+,(a0)+
	cmp.l	a0,a2
	bge.b	.copy

	movem.l	(sp)+,d0-a6


	move.l	4(a0),d0	; xfdbi_SourceBufLen
	sub.l	#PEN_size,d0
	move.l	d0,32(a0)	; xfdbi_TargetBufSaveLen

	move.l	60(a0),a1	; xfdbi_UserTargetBuf

	btst.b	#3,49(a0)	; XFDFB_USERTARGET,1+xfdbi_Flags
	bne.b	.CopyMem

	move.w	#1,18(a0)	; XFDERR_NOMEMORY,xfdbi_Error

	move.l	d0,28(a0)	; xfdbi_TargetBufLen

	move.l	4.w,a6		; execbase
	
	move.l	24(a0),d1	; xfdbi_TargetBufMemType
	
	move.l	a0,-(sp)
	jsr	-198(a6)	; AllocMem
	move.l	(sp)+,a0

	move.l	d0,a1
	move.l	d0,20(a0)	; xfdbi_TargetBuffer
	beq.b	.Cant


.CopyMem:
	clr.w	18(a0)		; xfdbi_Error
	
	move.l	32(a0),d0	; xfdbi_TargetBufSaveLen
	move.l	0(a0),a0	; xfdbi_SourceBuffer
	jsr	-624(a6)	; CopyMem


	moveq	#1,d0
	movem.l	(sp)+,d2-d7/a0-a6
	rts


.cant:
	movem.l	(sp)+,d2-d7/a0-a6
	rts



;--------------------------------------------------------------------
;--------------------------------------------------------------------


RemSMG2:
	movem.l	d2-d7/a0-a6,-(sp)

	moveq	#0,d0

	move.l	4(a0),d7		; xfdbi_SourceBufLen

	movem.l	d0-a6,-(sp)
	move.l	a0,a6
	move.l	0(a0),a0		; xfdbi_SourceBuffer


	move.l	8(a0),d0
	lsl.l	#2,d0
	lea.l	$14(a0,d0.l),a0

	cmp.w	#$3ea,2(a0)		; DATA
	beq.b	.okiej

	cmp.w	#$3e9,2(a0)		; CODE
	beq.b	.okiej

	movem.l	(sp)+,d0-a6
	bra.w	.cant

.okiej:
	addq.l	#4,a0

	move.l	a0,a5			; begin of codehunk


	;****** CORRECT HUNKLENGTHs...

	move.l	0(a6),a0		; xfdbi_SourceBuffer
	lea.l	$14(a0),a0
	sub.l	#SMG_size2/4,(a0)
	sub.l	#SMG_size2/4,(a5)

	;****** REPLACE STOLEN INSTRUCTION...

	move.l	#$61000002,d1

	move.l	a5,a0
	add.l	(a5),a0
	add.l	(a5),a0
	add.l	(a5),a0
	add.l	(a5),a0

	move.l	a5,a2			; BeginOfCodeHunk

.restore
	move.l	(a0),d2
	cmp.l	d1,d2
	bne	.none
	
	move.l	#$2c780004,(a0)		; restore MOVE.L 4.W,A6

.none
	addq.l	#2,d1
	subq.l	#2,a0
	cmpa.l	a0,a2
	bne	.restore

	;****** MAKE CLEAN COPY...


	move.l	4(a6),a2		; xfdbi_SourceBufLen
	sub.l	#SMG_size2,a2
	add.l	0(a6),a2		; xfdbi_SourceBuffer

	move.l	a5,a0			; before
	move.l	(a5),d0
	lsl.l	#2,d0
	add.l	d0,a0
	lea.l	SMG_size2(a0),a1	; after
	addq.l	#4,a1
	addq.l	#4,a0

.copy:
	move.l	(a1)+,(a0)+
	cmp.l	a0,a2
	bge.b	.copy

	movem.l	(sp)+,d0-a6


	move.l	4(a0),d0	; xfdbi_SourceBufLen
	sub.l	#SMG_size2,d0
	move.l	d0,32(a0)	; xfdbi_TargetBufSaveLen

	move.l	60(a0),a1	; xfdbi_UserTargetBuf

	btst.b	#3,49(a0)	; XFDFB_USERTARGET,1+xfdbi_Flags
	bne.b	.CopyMem

	move.w	#1,18(a0)	; XFDERR_NOMEMORY,xfdbi_Error

	move.l	d0,28(a0)	; xfdbi_TargetBufLen

	move.l	4.w,a6		; execbase
	
	move.l	24(a0),d1	; xfdbi_TargetBufMemType
	
	move.l	a0,-(sp)
	jsr	-198(a6)	; AllocMem
	move.l	(sp)+,a0

	move.l	d0,a1
	move.l	d0,20(a0)	; xfdbi_TargetBuffer
	beq.b	.Cant

.CopyMem:
	clr.w	18(a0)		; xfdbi_Error
	
	move.l	32(a0),d0	; xfdbi_TargetBufSaveLen
	move.l	0(a0),a0	; xfdbi_SourceBuffer
	jsr	-624(a6)	; CopyMem

	moveq	#1,d0
	movem.l	(sp)+,d2-d7/a0-a6
	rts
.cant:
	movem.l	(sp)+,d2-d7/a0-a6
	rts



;--------------------------------------------------------------------
;--------------------------------------------------------------------

RemSMG:
	movem.l	d2-d7/a0-a6,-(sp)

	moveq	#0,d0

	move.l	4(a0),d7		; xfdbi_SourceBufLen

	movem.l	d0-a6,-(sp)
	move.l	a0,a6
	move.l	0(a0),a0		; xfdbi_SourceBuffer


	move.l	8(a0),d0
	lsl.l	#2,d0
	lea.l	$14(a0,d0.l),a0

	cmp.w	#$3ea,2(a0)		; DATA
	beq.b	.okiej

	cmp.w	#$3e9,2(a0)		; CODE
	beq.b	.okiej

	movem.l	(sp)+,d0-a6
	bra.w	.cant

.okiej:
	addq.l	#4,a0

	move.l	a0,a5			; begin of codehunk


	;****** CORRECT HUNKLENGTHs...

	move.l	0(a6),a0		; xfdbi_SourceBuffer
	lea.l	$14(a0),a0
	sub.l	#SMG_size/4,(a0)
	sub.l	#SMG_size/4,(a5)

	;****** REPLACE STOLEN INSTRUCTION...

	move.l	#$61000002,d1

	move.l	a5,a0
	add.l	(a5),a0
	add.l	(a5),a0
	add.l	(a5),a0
	add.l	(a5),a0

	move.l	a5,a2			; BeginOfCodeHunk

.restore
	move.l	(a0),d2
	cmp.l	d1,d2
	bne	.none
	
	move.l	#$2c780004,(a0)		; restore MOVE.L 4.W,A6

.none
	addq.l	#2,d1
	subq.l	#2,a0
	cmpa.l	a0,a2
	bne	.restore

	;****** MAKE CLEAN COPY...


	move.l	4(a6),a2		; xfdbi_SourceBufLen
	sub.l	#SMG_size,a2
	add.l	0(a6),a2		; xfdbi_SourceBuffer

	move.l	a5,a0			; before
	move.l	(a5),d0
	lsl.l	#2,d0
	add.l	d0,a0
	lea.l	SMG_size(a0),a1	; after
	addq.l	#4,a1
	addq.l	#4,a0

.copy:
	move.l	(a1)+,(a0)+
	cmp.l	a0,a2
	bge.b	.copy

	movem.l	(sp)+,d0-a6


	move.l	4(a0),d0	; xfdbi_SourceBufLen
	sub.l	#SMG_size,d0
	move.l	d0,32(a0)	; xfdbi_TargetBufSaveLen

	move.l	60(a0),a1	; xfdbi_UserTargetBuf

	btst.b	#3,49(a0)	; XFDFB_USERTARGET,1+xfdbi_Flags
	bne.b	.CopyMem

	move.w	#1,18(a0)	; XFDERR_NOMEMORY,xfdbi_Error

	move.l	d0,28(a0)	; xfdbi_TargetBufLen

	move.l	4.w,a6		; execbase
	
	move.l	24(a0),d1	; xfdbi_TargetBufMemType
	
	move.l	a0,-(sp)
	jsr	-198(a6)	; AllocMem
	move.l	(sp)+,a0

	move.l	d0,a1
	move.l	d0,20(a0)	; xfdbi_TargetBuffer
	beq.b	.Cant


.CopyMem:
	clr.w	18(a0)		; xfdbi_Error
	
	move.l	32(a0),d0	; xfdbi_TargetBufSaveLen
	move.l	0(a0),a0	; xfdbi_SourceBuffer
	jsr	-624(a6)	; CopyMem


	moveq	#1,d0
	movem.l	(sp)+,d2-d7/a0-a6
	rts


.cant:
	movem.l	(sp)+,d2-d7/a0-a6
	rts


