ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÚÄ Threads in Ring-0 under Win95/98 Ä¿ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ³ by ³ ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ ÀÄÄÄÄÄÄÄÄÄÄÄ Benny / 29A ÄÄÄÄÄÄÄÄÄÄÄÄÙ ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ 1. Disclamer ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ The followin' document is an education purpose only. Author isn't responsible for any misuse of the things written in this document. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ 2. Foreword ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Welcome to my second article, which describes threads under windows. I hope, u will enjoy it as much as first one. Becoz things described below r not documented in some acceptable form and becoz I had to learn it all by try-mistake way, it is very possible some things won't run in future versions of windows (if it will even run X-D). Forgive it to me and if u will have any notes about this article, I would be grateful, if u'll gimme know. Thanx. To understand this article u must know, what's Ring-0 and Ring-3 level. There r many kewl tutorials about rings, so I decided to not repeat, what otherz already wrote. Enjoy this article! ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ 3. Introduction ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Threads in Ring-0, ain't it a bit crazy, eeh? :) Yeah, maybe, nevertheless it is possible to code Ring-0 multithreaded virus and it really worx. And as I said earlier, this stuff is undocumented. Don't worry, it worx on Win95/98 now and I hope it will also work in future versions of Win95 compatible operating system. U probably ask me: "Why da fuck should I use threads in my virus?". Its simple. Many reasons r commented in my first tutorial "Threads and fibers under Win32", but here I can say, that it's one of the best anti-heuristic techniques. U can use threads in your Ring-0 virus. U can also use it in resident viruses to fuck some heuristic monitors. And using combination of Ring-0 and Ring-3 threads is very kewl Anti-AV technique. And also, very good usage of threads is as "thing in the middle" to stay resident in memory. System threads r present in memory, until anyone will terminate them. Ain't it charming? How to do it? Continue reading... ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ 4. Creating threads in Ring-0 ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ In Ring-3 we use CreateThread API function to create threads. This API (under Win95/98) doesn't call any vxd service to create thread, it does that dirty work on application level. If we want to create threads under Ring-0, we have to use vxd service, becoz we haven't access to APIs. Creating threads in Ring-0 is very powerful tool. We have two choices, how to do that: - from Ring-0 create Ring-3 thread - from Ring-0 create Ring-0 thread Well, first things your virus has to do is: - jump to Ring-0 (IDT method, for instance) - allocate some shared memory (heap, for instance) I assume, everything of that is already done and we can create some new thread now... 4.1 Creating new Ring-3 thread ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ VMM (virtual machine/memory manager) allows us to use many vxd services, and one of them is VMMCreateThread service. Let's see, what Microsoft Windows 98 DDK says: ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ VMMCall VMMCreateThread, ³ ³ or eax, eax ³ ³ jz thread_not_created ³ ³ ³ ³ ³ ³ Creates a protected mode thread in the system virtual machine and starts ³ ³ it executing in ring 3 at the instruction specified by CS:EIP. Uses all ³ ³ registers and Flags. ³ ³ ³ ³ ³ ³ * Returns the handle of the new thread in EAX if successful; otherwise, ³ ³ returns 0 in EAX. ³ ³ ³ ³ * initial_ss,initial_esp,initial_cs,initial_eip,initial_ds,initial_es ³ ³ Ring 3 protected mode registers used to start the thread. ³ ³ ³ ³ * ThreadType ³ ³ Programmer-defined DWORD value a VxD can use to uniquely identify the ³ ³ threads that it creates. Typically, this value is a pointer to the ³ ³ VxD's DDB because the pointer is unique among VxDs. This value is ³ ³ stored in the TCB_ThreadType field of the thread's control block. ³ ³ ³ ³ * InitCallback ³ ³ Ring 0 initialization function that is called after the Thread_Init ³ ³ message is sent. ³ ³ ³ ³ * RefData ³ ³ Programmer-defined DWORD value that is passed, in EDX, to the ³ ³ InitCallback function. ³ ³ ³ ³ ³ ³ This service is intended for use only by Windows internal system ³ ³ components. A virtual device should not use this service because it can ³ ³ cause the system to become unstable. ³ ³ ³ ³ The client registers are initialized to the values specified by the ³ ³ procedure parameters. The values must be valid values for ring 3; do not ³ ³ use ring 0 selectors. ³ ³ ³ ³ The Create_Thread and Thread_Init messages are sent to all virtual ³ ³ devices, and the timeslice scheduler is notified to start scheduling the ³ ³ thread. ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ OK, we have very good documentation to Ring-3 threads, which can be created in Ring-0, so we can start with code example: push eax ;random sh!t push offset Callback ;address of callback routine push 'fuck' ;ID push 187h ;ES register push 187h ;DS register push offset Thread ;EIP - address of Thread proc push 17fh ;CS register push offset tstack ;ESP - address of Thread stack push 187h ;SS register VxDCall VMMCreateThread ;create thread! add esp, 24h ;clean stack test eax, eax ;thread successfuly created? je error ;nope ;( Well, now u would like to know, what sense this block of code has, rite? OK, I will explain it to u step by step: 1) First parameter is parameter, which will be passed to ring-0 callback routine. Callback routine should contain CLC and RET instructions. It is long history of this and I don't think this is rite place for explaining it here. 2) Address of callback routine. 3) ID number of thread, which will be stored in THCB structure. This should be whole system unique number, so take care with choosing it. THCB is also long history and it ain't important to explain it here, what is it. 4) ES, DS and SS registers has under Win95/98 187h value (Ring-3 selector values). U shouldn't use Ring-0 selectors. 5) EIP is address of new thread procedure. 6) CS register has under Win95/98 17fh value (Ring-3 selector value). 7) ESP is address of new thread stack. Don't forget, that ESP must point to TOP OF STACK, so do not use: tstack db 1000h dup (?) and use: db 0fffh dup (?) tstack db ? Also do not forget to have enough memory space for stack, or u can rewrite some data or code! 8) VxDCall VMMCreateThread can be also written as: int 20h ;VxDCall dd 00010105h ;VMMCreateThread 9) This service doesn't clean stack, so u have to clean it by "ADD ESP, 24h" or "SUB ESP, -24h" instruction. 10) U will get thread Ring-3 handle, if thread will be successfuly created. Otherwise service will return NULL in EAX. Is it clear? If thread is successfuly created, that new thread is running paralelly with other threads in your system. This thread has low priority and will run in system until u will terminate it (whole session!). So, once u will create thread, it will run until u will terminate it. Thread can be terminated by VMMTerminateThread (00010107h) service. Problem is, that thread can be terminated only from Ring-0 (becoz VMMTerminateThread is Ring-0 service). So, u can send "message" (e.g. by releasing semaphore) to your Ring-0 code to terminate thread. This is a bit impractic. In my Win98.BeGemot virus, which creates only one VMM thread at once session, is code, which will cause thread to sleep for whole session. The good thing on it is that u can simply "kill" your thread, what means that processor won't commit any CPU time at whole session. The bad thing is that your thread will stay present in memory and will still use system resources (memory). It ain't recommended to use it, when u dynamically creating threads. Imagine, in every activation of your Ring-0 will be created new thread, which will be lately killed. After 100 activations, u would have 100 threads in memory. Choose, what is better for u. Here u have two examples: Sleep example: ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ New_Thread: push -1 ;never wake up push 002a0009h ;thread sleep service call VxDCall0 ;VxDCall0 from ring3 to ring0 Semaphore example: ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Ring0_proc: xor ecx, ecx ;ECX = 0 mov cl, 0 ;semaphore can be 0 or 1 semaphore = byte ptr $-1 jecxz continue ;0? Then continue mov edi, 12345678h ;push thread handle tHandle = dword ptr $-4 VxDCall VMMTerminateThread ;terminate thread mov [semaphore], 0 ;set semaphore continue: VxDCall VMMCreateThread ;create new thread mov eax, [tHandle] ... ;next action ret ;exit New_Thread: mov [semaphore], 1 ;set semaphore jmp $ ;infinite loop, wait for ;termination I hope this is clear. 4.2 Creating new Ring-0 thread ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Real phun is goin' here. Before I will explain u, how to create Ring-0 thread, I will explain Ring-0 principles. I assume, u know, what ring levels r, so I will talk here only about details. U know, that Win95/98 r preemptive multitasking multithreading operating system. Problem (maybe problem, maybe not) is reentrancy. Win95/98 r switching preemptively between threads only when they run in Ring-3. If any thread is actualy in Ring-0, Win95/98 won't be able to switch to another thread. U should know it from your previous Ring-0 programming. Try to make infinite loop at simple Win32 application and at Ring-0 application, and u will c, what will happen --> At Win32 application, Win95/98 will run on, but at Ring-0 application, Win95/98 will halt. That's very important thing on Ring-0 programming. So when u will create new Ring-0 thread, system will commit CPU time only to that thread, until thread will be finished. Remember it! In Win95/98 is one vxd service, which allows us to create "another level" threads. Here u have description from Microsoft Windows 98 DDK: ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ _VWIN32_CreateRing0Thread ³ ³ ³ ³ Provides a service for ring 0 clients to create Win32 threads that ³ ³ execute only at ring 0, which allows the use of Win32 blocking ³ ³ functions. Preserves EBX, EDI, ESI, EBP, and segment registers. ³ ³ ³ ³ * Returns a Win32 ring 3 handle in EAX and a ring 0 thread handle in EDX ³ ³ if successful; otherwise EAX contains 0. ³ ³ ³ ³ * ECX ³ ³ The size of the ring 3 stack for the thread being created. The ³ ³ recommended stack size is 4096. ³ ³ ³ ³ * EDX ³ ³ DWORD to pass to startup function specified in ESI. ³ ³ ³ ³ * EBX ³ ³ Pointer to ring 0 function where execution starts. ³ ³ ³ ³ * ESI ³ ³ If this is a synchronous thread create, specify FALSE. Otherwise ³ ³ the value is the address of a callback procedure that is called if the ³ ³ create fails. The DWORD parameter passed in EDX is passed to the ³ ³ callback procedure. ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Now, let's have an example of code: mov ecx, 1000h ;thread stack mov ebx, offset Thread ;address of thread xor esi, esi ;synchronous thread VxDCall _VWIN32_CreateRing0Thread ;Create thread! ;... ;code continues after ;thread termination Thread: pushad ;store all registers jmp tNext ;jump over three bytes db 3 dup (?) ;3 bytes (see below) tNext: ... ;thread action popad ;restore all registers ret ;and let OS to ;terminate it OK, I assume, first part of code (thread creation) is clear. Second part ain't so clear, as it loox. Let's c, what it really does: 1) Thread will store all registers. Those register will be l8r used for termination of thread. 2) Then will thread jump over 3 bytes. Those bytes will be l8r overwritten (don't ask me why) by something(?). Really don't ask me why, coz I don't really know. Nevertheless, with this 5 byte long correction it worx without any problems. 3) Thread will restore all registers and quits. System will automaticaly terminate thread, coz on the stack is placed address of the routine, which will do that. NOTE: "VxDCall _VWIN32_CreateRing0Thread" can be also written as: int 20h ;VxDCall dd 002A0013h ;_VWIN32_CreateRing0Thread ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ 5. Closin' ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ I think, there's nothing more to say. Imagine, what everything can u do with Ring-0/Ring-3 threads. Anti-AV, neural-nets, communication interface, memory residency, and REALLY much more! Use it as u want, just don't forget, who wrote this tute X-D. Also, I would like to greet all my real friends from IRC and Amsterdam VX meeting. Here r some greetz to them: Darkman........ Thank you for nice holidays, my friend! Btw, u still owe me some viriis - don't forget, we won that pool! :) Super.......... Still optimizing yourself? X-D GriYo.......... Hey man, nice to met ya! Reptile........ Huh, never seen human, who can smoke more than u! It was hard to hold step with u! |-) Billy Belcebu.. Czech beer? No problem! Btw, why don't u try to write article about .txt's ? ;)) Wintermute..... Nice to met you, thanx for nice whiles. StarZer0....... Hey, let's finish our virus! X-D Eddow.......... When will we finish that WinNT Ring-0 virus? :) Rilo........... Thanx for everything (accomodation, food, CD). I owe it to u, come to .cz! JQwerty........ Come back to 29A, my teacher! Qozah.......... Well, when will we start working on that thread/neural net project? Prizzy......... Nezajdem negdy na pivo? :))) Ale ja to myslim vazne! Int13h......... Mbate kopio hina? :) Inspiration.... Please, spend with me more time X-DD. ÚÄÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³ Benny / 29A, 1999 º ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ