Jump to content

Trace vector decoder

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by 142.203.1.9 (talk) at 12:11, 8 April 2021 (Microprocessor tracing: Control is gained on the microprocessor, not necessarily the machine). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

A Trace Vector Decoder (TVD) is computer software that uses the trace facility of its underlying microprocessor to decode encrypted instruction opcodes just-in-time prior to execution and possibly re-encode them afterwards. It can be used to hinder reverse engineering when attempting to prevent software cracking as part of an overall copy protection strategy.

Microprocessor tracing

Certain microprocessor families (e.g. 680x0, x86) provide the capability to trace instructions to aid in program development. A debugger might use this capability to single step through a program, providing the means for a programmer to monitor the execution of the program under test.

By installing a custom handler for the trace exception, it is possible to gain control of the microprocessor between the execution of every instruction. A typical trace vector decoder exception handler decodes the upcoming instruction located outside the exception, as well as re-encoding the previously decoded instruction.

Implementations

Motorola 680x0

The Motorola 68000 has an instruction-by-instruction tracing facility.[1] When its trace state is enabled, the processor automatically forces a trace exception after each (non-exception) instruction is executed. The following assembly code snippet is an example of a program initializing a trace exception handler on a 68000 system.

InstallHandler:	MOVE.L	#$4E730000,-(SP)       ; Push trace exception handler on to stack
                MOVE.L	#$00000010,-(SP)
                MOVE.L	#$0004DDB9,-(SP)
                MOVE.L	#$BD96BDAE,-(SP)
                MOVE.L	#$B386B586,-(SP)
                MOVE.L	#$D046D246,-(SP)
                MOVE.L	#$0246A71F,-(SP)
                MOVE.L	#$00023C17,-(SP)
                MOVE.W	#$2C6F,-(SP)
                MOVE.L	SP,($24).W             ; Set trace exception handler vector
                ORI.W	#$A71F,SR              ; Enable trace state
                NOP                            ; CPU generates a trace exception after executing this NOP
                ;------------------------
                ...                            ; Code from this line would be encrypted

The following is a disassembly of the above trace exception handler loaded on the stack. The purpose of this handler is to obfuscate any traced encrypted code. Its decryption process is affected by the contents of the condition code register (CCR). For example, an arithmetic operation in the main program having the 0 number as a result, will cause zero flag bit to be set in CCR. This will cause the value in (SP) to be changed in the trace exception handler.

TraceHandler:   MOVE.L	(2,SP),A6              ; Load return address from supervisor stack
                MOVE.W	(SP),D6                ; Load condition codes of the main program
                AND.W	#$A71F,D6
                ADD.W	D6,D0
                ADD.W	D6,D1
                EOR.L	D1,D6
                EOR.L	D2,D6
                EOR.L	D6,(A6)                ; Decode 8 bytes ahead in main
                EOR.L	D6,(4,A6)
                RTE                            ; Return from exception

Intel x86

The x86 CPUs provide a trace flag that generates an interrupt after the execution of each instruction. The following assembly code is an example of how this might be implemented on an 8086 system.

InstallHandler: xor     bx, bx                 ; Set trace interrupt handler vector
                mov     es, bx
                mov     word ptr es:[1*4], offset TraceHandler
                mov     word ptr es:[1*4 + 2], cs

                pushf                          ; Turn on the trace trap
                pop     ax
                or      ah, 1
                push    ax
                popf

                nop
                ;------------------------
                ...                            ; Code from this line would be encrypted

The following is a disassembly of an associated trace interrupt handler.

TraceHandler:   push    bp
                mov     bp, sp                 ; Gain access to return address
                push    bx
                push    ds                     ; Return address in DS:BX

                lds     bx, 2[bp]              ; Pointer to opcode of next instruction
                mov     bx, [bx]               ; Get current instruction's opcode

                ...                            ; Decode the opcode

                pop     ds
                pop     bx 
                pop     bp
                iret                           ; Return from interrupt

Examples

Copylock

The Rob Northen Copylock system implemented on the Amiga,[2] Atari ST[3] and IBM PC[4] platforms includes a TVD. In addition to its general software encryption, the Copylock TVD obfuscates the code that accesses and validates the copy protected diskette.

Demoscene

A TVD was included in the Voyage demo, written for the 680x0-based Commodore Amiga by Razor 1911.[5]

References

  1. ^ "MC68000 16-Bit Microprocessor Advance Information" (PDF). Motorola Inc.
  2. ^ Sevalliu, Patrik. "Rainbow Islands". Computer Archeology.
  3. ^ Kerr, Wayne (May 2004). "Amiga cracking – A look at basic TVD's". Flashtro.
  4. ^ Furlough, Fabulous. "Rob Northen's Copylock". My life behind the patch.
  5. ^ Various. "Vogage Demo". Pouet.