Basics of SMC

Newcomer - Board
Verfügbare Informationen zu "Basics of SMC"

  • Qualität des Beitrags: 0 Sterne
  • Beteiligte Poster: 4dministr4t0r
  • Forum: Newcomer - Board
  • Forenbeschreibung: Forum für alle "Newcomer" (Alter, Geschlecht etc. egal), die sich im Bereich Systemsicherheit weiterbilden wollen. Chatten könnt Ihr am Ende der Seite!
  • aus dem Unterforum: Tutorials (Info-Texte)
  • Antworten: 1
  • Forum gestartet am: Samstag 23.12.2006
  • Sprache: deutsch
  • Link zum Originaltopic: Basics of SMC
  • Letzte Antwort: vor 17 Jahren, 3 Monaten, 30 Tagen, 21 Stunden, 54 Minuten
  • Alle Beiträge und Antworten zu "Basics of SMC"

    Re: Basics of SMC

    4dministr4t0r - 25.12.2006, 20:45

    Basics of SMC
    ##############################################################################################

    Alle hier geposteten Tutorials sind im www zu finden und nicht von mir. Sie werden unverändert hier dargestellt.

    Wir weisen ausdrücklich darauf hin, daß wir mit dieser Ansammlung nicht zu Straftaten aufrufen oder animieren wollen!!!
    Alle Tutorials dienen ausschließlich zu Informationszwecken.

    Solltest Du ein von Dir erstelltes Tutorial hier finden und mit der Veröffentlichung bei Hackressort nicht einverstanden sein, schick mir eine PM oder Email.

    Das Tutorial wird dann entfernt.

    Hackressort-Team

    ##############################################################################################


    ::::::::: :::::::: ::::::::: ::::::::::
    :+: :+: :+: :+: :+: :+: :+:
    +:+ +:+ +:+ +:+ +:+ +:+
    +#++:++#+ +#++:++#++ +#++:++#: :#::+::#
    +#+ +#+ +#+ +#+ +#+ +#+
    #+# #+# #+# #+# #+# #+# #+#
    ######### ######## ### ### ###

    http://blacksun.box.sk
    ____________________
    _______________________I Topic: I_____________________
    \ I Basics of SMC I /
    \ E-mail: I I Written by: /
    > I I <
    / fu@ckz.org I____________________I Ralph \
    /___________________________> <_________________________\


    Basics of SMC
    by Ralph (fu@ckz.org)
    -AWC (http://awc.rejects.net)
    Version:
    Date:


    1. Introduction
    -About this thing
    -Who should read this?
    -What is SMC?

    2. Opcode Modification

    3. Encryption

    4. Sample Code

    5. Conclusion



    1. Introduction
    ================


    About this thing
    ----------------
    This file makes an attempt to explains the very basics of Self Modifying Code.
    All code in here is presented in assembly, so I assume that you have at least an
    understanding of the concepts behind it. In addition you would have to be familiar
    with some hardware, specificly memory and CPU, details.


    Who should read this?
    ---------------------
    If you are new to this concept and are interested in the areas of commercial programming
    or virus programming, or something similar you might find the information provided
    useful. The reasons for developing SMC code vary greatly. Two of the more common
    reasons are:
    1. Stealth
    -Viruses need to hide themselfs from detection. Many of todays viruses implement
    some form of SMC
    2. Anti-debugging
    -Commercial programs that try to keep the source code a secret will benefit from SMC
    as some t3kn33kz can successfully stop inexperienced crackers from finding out what
    the code actually does.



    2. Opcode Modification
    =======================
    Opcode modification is the process of changing the value of an instruction before it
    is actually executed. The basic form is:
    MOV REGISTER,CODE
    MOV [ADDRESS],REGISTER
    Where REGISTER is any temporary register, CODE is the new code to be written, and
    [ADDRESS] is the address where the new code should be placed. This method can however
    be a bit tricky because you basicly have to work at the binary level at times. A
    variation of this approach is to place the code to be written into a memory location
    which will never get executed. Here is a simply sample program to demostrate this:

    MAIN SEGMENT
    ASSUME CS:MAIN,DS:MAIN

    ORG 100h ;define entry point

    START:
    CALL MODIFY ;call modification routine

    BLAH:
    MOV AH,09h ;this code will get overwritten
    MOV DX,OFFSET HELLO ;useless code
    INT 21h ;call interrupt 21h

    MODIFY: ;routine to change word, try hidding it somewhere
    MOV DI,OFFSET NEWBYTES ;put location of the new instruction into DI
    MOV WORD PTR [BLAH],DI ;move DI to the memory area to be changed
    RET ;return to caller

    NEWBYTES: ;new instruction to be executed
    MOV AH,4Ch ;DOS' terminated program interrupt

    HELLO DB "Hello World$" ;useless data

    MAIN ENDS
    END START

    If someone where to disassemble this code they would get output similar to this:

    1: 11AA:0100 E80700 CALL 010A
    2: 11AA:0103 B409 MOV AH,09
    3: 11AA:0105 BA1401 MOV DX,0114
    4: 11AA:0108 CD21 INT 21
    5: 11AA:010A BF1201 MOV DI,0112
    6: 11AA:010D 893E0301 MOV [0103],DI
    7: 11AA:0111 C3 RET
    8: 11AA:0112 B44C MOV AH,4C

    Most people would simply assume that the lines 2-4 will just print the string located
    at offset 0114, when infact line 2 gets replaced with line 8. The result is that after
    the the routine returns control to the caller the code will look like this:

    1: 11AA:0100 E80700 CALL 010A
    2: 11AA:0103 B409 MOV AH,4C
    3: 11AA:0105 BA1401 MOV DX,0114
    4: 11AA:0108 CD21 INT 21
    5: 11AA:010A BF1201 MOV DI,0112
    6: 11AA:010D 893E0301 MOV [0103],DI
    7: 11AA:0111 C3 RET
    8: 11AA:0112 B44C MOV AH,4C

    So the actual code that gets executed will simply terminate the program.
    By the way, one way to maybe optimize this code is to replace the MODIFY routine
    with this one:

    MODIFY:
    PUSH WORD PTR [NEWBYTES]
    POP WORD PTR [BLAH]
    RET

    Stack operations are quite fast, but I am not sure of they are actually faster than
    those two MOV instructions. Try running it through a timer.
    Obviously this was just a simple example, but you should be able to understand the
    general idea behind SMC.



    3. Encryption
    ==============
    Encryption is when the actual bits in your program are modifyed. The most common
    and easiest method is to perform a XOR operation on each bit of your code. I am not
    sure what the most efficient method of doing so is as I have not devoted too much time
    to SMC, but I came up with a routine that seems to do the job just fine.
    The program will actually have two runtime versions. One to do the initial XOR for
    the first time run, this version will also create the second version. The second
    version contains the body of the program in a XORed format, and contains another XOR
    procedure at the beginning.

    First Run:
    ---------------
    | XOR Program |
    ---------------
    | Write File |
    ---------------
    | XOR Program |
    ---------------
    | |
    | Program |
    | |
    ---------------

    Every Other Run:
    ---------------
    | XOR Program |
    ---------------
    | |
    |XORed Program|
    | |
    ---------------

    Sorry about the lame ASCII, but hopefully you can better visualize the proccess this
    way. Anyway, here is the code for the program:

    MAIN SEGMENT
    ASSUME CS:MAIN,DS:MAIN

    ORG 100h

    START:
    MOV CX,DONE-BODY ;put size to xor into CX
    MOV BX,OFFSET BODY ;and xor location into BX

    XOR_1:
    XOR WORD PTR [BX],0FFFFh ;xor word located at BX with our xor mask (0FFFFh)
    INC BX ;increment index
    INC BX ;and again since its 16 bits, and inc only adds 8

    DEC CX ;decrement counter
    DEC CX ;again for same reason as above
    CMP CX,00h ;check if done encrypting
    JNE XOR_1 ;return to xor routine if not

    CALL WRITE ;call procedure to write out new file
    INT 20h ;and exit, new file was created

    REAL_START:
    MOV CX,DONE-BODY ;put size to xor into CX
    MOV BX,OFFSET BODY-REAL_START+100h ;and xor location into BX

    XOR_2:
    XOR WORD PTR [BX],0FFFFh ;xor word located at BX with our xor mask (0FFFFh)
    INC BX ;increment index
    INC BX ;and again since its 16 bits, and inc only adds 8

    DEC CX ;decrement counter
    DEC CX ;again for same reason as above
    CMP CX,00h ;check if done encrypting
    JNE XOR_2 ;return to xor routine if not

    BODY: ;some instructions to test if this thing worked
    INT 20h
    INT 20h
    INT 20h

    DONE:

    WRITE PROC ;Procedure to write new, xored, file
    @@OPEN_FILE:
    MOV AX,3D02h ;Open File function, returns file handle in AX
    MOV DX,OFFSET FILENAME
    INT 21h

    @@WRITE_FILE: ;Write to Device function
    MOV BX,AX ;BX contains device handle
    MOV AH,40h
    MOV CX,OFFSET DONE - OFFSET REAL_START
    MOV DX,OFFSET REAL_START ;location of buffer
    INT 21h ;do it

    @@CLOSE_FILE: ;Close File function
    MOV AH,3Eh
    INT 21h

    RET ;return to caller
    WRITE ENDP

    FILENAME DB "XOR1.COM",0 ;new file

    MAIN ENDS
    END START

    Might be a bit hard to understand at first glance, but there is nothing to it. CX gets
    loaded with the size of bytes to be XORed for use in the loop later on, BX gets loaded
    with the location of the bytes to be XORed. BX is the only general purpose register
    that can be used for indexing. The line
    XOR WORD PTR [BX],0FFFFh
    performs the actual XOR. 0FFFFh is a bit mask. Any number will do for this as long as
    you use the same for encrypting and decrypting. Now, what does this code look like to
    somone trying to disassemble it? Well the program created after the first run
    (XOR1.COM) looks like this before execution:

    1. 11B0:0100 B90600 MOV CX,0006
    2. 11B0:0103 BB1201 MOV BX,0112
    3. 11B0:0106 8337FF XOR WORD PTR [BX],-01
    4. 11B0:0109 43 INC BX
    5. 11B0:010A 43 INC BX
    6. 11B0:010B 49 DEC CX
    7. 11B0:010C 49 DEC CX
    8. 11B0:010D 83F900 CMP CX,+00
    9. 11B0:0110 75F4 JNZ 0106
    10. 11B0:0112 32DF XOR BL,BH
    11. 11B0:0114 32DF XOR BL,BH
    12. 11B0:0116 32DF XOR BL,BH

    Notice how the actual body of the program (lines 10-12) are not what they are supposed
    to be. During execution the program looks like this:

    1. 11B0:0100 B90600 MOV CX,0006
    2. 11B0:0103 BB1201 MOV BX,0112
    3. 11B0:0106 8337FF XOR WORD PTR [BX],-01
    4. 11B0:0109 43 INC BX
    5. 11B0:010A 43 INC BX
    6. 11B0:010B 49 DEC CX
    7. 11B0:010C 49 DEC CX
    8. 11B0:010D 83F900 CMP CX,+00
    9. 11B0:0110 75F4 JNZ 0106
    10. 11B0:0112 CD20 INT 20
    11. 11B0:0114 CD20 INT 20
    12. 11B0:0116 CD20 INT 20

    Now we have our original program back.
    Again, this program was very simplistic. Some major areas you could "upgrade" on are
    error checking and speed. As you can see I am basicly wasting 10 bytes of code on
    a duplicated procedure. Anyway, it was just an idea I had and it seems to work fine
    for my purposes.



    4. Sample Code
    ===============
    Here is some sample source that combines the two techniques. The password is stored
    in XORed format and the messages are switched around.

    MAIN SEGMENT
    ASSUME CS:MAIN,DS:MAIN

    ORG 100h

    START:
    CALL MODIFY

    MOV AH,09h
    MOV DX,OFFSET ENTER_PASS ;"Enter password:"
    INT 21h

    MOV SI,OFFSET STRING ;Load up our string register
    XOR CX,CX ;and a counter to keep track of the string length

    READ_STRING:
    MOV AH,00h ;BIOS interupt for Get Key Board Buffer
    INT 16h

    CMP AL,0Dh ;INT 16h returns the key pressed in AL
    JE CHECK_STRING ;so we check if it was Enter and quite if so

    MOV AH,02h ;we gotta echo back the key
    MOV DL,AL
    INT 21h

    MOV [SI],AL ;move key into first item of array (STRING)
    INC SI ;and increment the string pointer
    INC CX ;keep track of how many keys have been pressed

    CMP CX,09h ;if more than 8, display error
    JGE TOO_LONG

    JMP READ_STRING ;otherwise return and read next key

    CHECK_STRING:
    MOV CX,08h ;put size to xor into CX
    MOV BX,OFFSET PASS ;and xor location into BX

    XOR_:
    XOR WORD PTR [BX],0FFFFh ;xor word located at BX with our xor mask (0FFFFh)
    INC BX ;increment index
    INC BX ;and again since its 16 bits, and inc only adds 8

    DEC CX ;decrement counter
    DEC CX ;again for same reason as above
    CMP CX,00h ;check if done encrypting
    JNE XOR_ ;return to xor routine if not

    CMP_PASS:
    MOV CX,08h ;size of string to compare
    MOV SI,OFFSET STRING ;load SI and DI with the two strings to compare
    MOV DI,OFFSET PASS
    REP CMPSB ;do the comparison
    JNE INVALID_PASS ;and branch of

    CORRECT_PASS: ;this will display "Invalid Password"
    MOV AH,09h
    CHANGE_1:
    MOV DX,OFFSET INVALID_MSG
    INT 21h
    INT 20h

    INVALID_PASS: ;this will display "Correct Password"
    MOV AH,09h
    CHANGE_2:
    MOV DX,OFFSET CORRECT_MSG
    INT 21h
    INT 20h

    TOO_LONG:
    MOV AH,09h
    MOV DX,OFFSET T00_LONG_ ;"Password too long"
    INT 21h
    INT 20h

    CHANGE1:
    MOV DX,OFFSET CORRECT_MSG ;new string to replace CHANGE_1

    CHANGE2:
    MOV DX,OFFSET INVALID_MSG ;new string to replace CHANGE_2

    MODIFY: ;routine to change the two
    PUSH WORD PTR [CHANGE1 + 1]
    POP WORD PTR [CHANGE_1 + 1]

    PUSH WORD PTR [CHANGE2 + 1]
    POP WORD PTR [CHANGE_2 + 1]

    RET


    ENTER_PASS DB "Enter password: $"
    CORRECT_MSG DB 0Ah,0Dh,"Correct Password",0Ah,0Dh,"$"
    INVALID_MSG DB 0Ah,0Dh,"Invalid Password",0Ah,0Dh,"$"
    T00_LONG_ DB 0Ah,0Dh,"Password too long",0Ah,0Dh,"$"
    PASS DB 097h,0CBh,087h,0CFh,08Dh,0CCh,09Bh,0DEh ;XORed password
    STRING DB 08h DUP (?) ;buffer to hold password
    MAIN ENDS
    END START

    The password is "h4x0r3d!". Assemble as a .COM file and see what the result is.


    5. Conclusion
    ==============
    The two techniques discussed above are both best suited for two different kinds of
    programs. The opcode modification is meant to trick humans into thinking your code
    does something it does not, thus it is best for anti-dedugging. The encryptor
    technique however does not produce output ment for humans. Most of the time it does
    not even produce valid opcodes, thus its main purpose is to fool machines. A virus
    might benefit from this one.
    One important thing to keep in mind is that you should always get your program
    completly working before you even think about making self modifying. Otherwise you
    are just asking for trouble.
    And another thing, some CPUs require you to modify the instructions a certain amount
    of ticks before their execution due to read ahead and shit like that. Check your CPU
    documentation for exacact numbers. Sadly most of those are not available these days,
    and I have yet to figure out a way to get them on a CPU with a dynamic pre-fetch que.
    If your program is supposed to run on a 486 or lower, you can give the following
    program a try. I'm not sure if it actually works as I only have one computer to test
    it on, but it seems to do the job. It should return the buffer size of the pre-fetch
    units que.

    MAIN SEGMENT
    ASSUME CS:MAIN,DS:MAIN

    ORG 100h

    START:
    MOV AX,CS
    MOV ES,AX
    MOV CX,80h
    MOV DI,OFFSET QUE
    MOV AL,90h
    CLD
    REP STOSB

    XOR BX,BX
    MOV CX,80h
    MOV DI,OFFSET QUE+80h-1
    STD
    MOV AL,80h
    OUT 70h,AL
    CLI
    MOV AX,43h
    REP STOSB
    MOV DL,1

    LOAD_PF:
    DIV DL
    DIV DL
    DIV DL
    DIV DL
    DIV DL
    DIV DL
    DIV DL
    DIV DL

    QUE DB 80h DUP (90h)

    XOR AL,AL
    OUT 70h,AL
    STI
    CLD
    MOV AX,80h
    SUB AX,BX

    ;this part translates the result into ASCII, the _ after the lables is to
    ;keep tasm from complaining

    MOV BX,OFFSET TABLE_
    MOV CX,04h

    LOOP_:
    PUSH AX
    MOV AL,Ah
    SHR AL,04h
    XLAT

    MOV DL,AL
    MOV AH,02h
    INT 21h

    POP AX
    SHL AX,04h
    DEC CX
    CMP CX,00h
    JNE LOOP_

    MOV AH,02h
    MOV DL,'h'
    INT 21h
    INT 20h

    TABLE_ DB "0123456789ABCDEF"

    MAIN ENDS
    END START


    You may freely distribute this text as long as you don't change anything. If there's
    something you think should be changed, contact me first.

    Please always get the newest version of this and other tutorials at
    http://awc.rejects.net as they usually contained updated information, and addons.

    Send feedback to fu@ckz.org



    Mit folgendem Code, können Sie den Beitrag ganz bequem auf ihrer Homepage verlinken



    Weitere Beiträge aus dem Forum Newcomer - Board

    Hallo an die Runde - gepostet von sebuka am Mittwoch 21.03.2007



    Ähnliche Beiträge wie "Basics of SMC"

    Die wichtigsten Regel-Basics für Einsteiger - Thareas (Sonntag 10.06.2007)
    Basics - Hase (Dienstag 24.07.2007)
    Limp Bizkit Back To Basics Tour - Fredi (Donnerstag 14.07.2005)
    treffen in oldenburg - sky (Freitag 22.02.2013)
    Ginuwine - Back II Da Basics - ymaster (Mittwoch 24.05.2006)
    Back to Basics...training! - Chad (Montag 20.11.2006)
    Graupner SMC 16SCAN oder Schulze alpha-8.35w - Rabbit_1 (Sonntag 27.05.2007)
    ~Entscheidungen~ & ~ Der Ebay-Junkie~ - Lenchen (Dienstag 03.02.2009)
    Basics - sirseni (Freitag 25.05.2007)
    Fake Angriffe + Basics für den Wachturm - bastimw (Montag 13.11.2006)