Unveiling of Epsilon Anti-Virus

Pages: 1... 34567... 10
The executable at the moment is 14mb including the drivers which are embedded into the exe, read for dropping.

Anyway the source code is the one which is 1GB.


How could 14 megabytes hold as much information as 1 gigabyte, especially since we talk about source code and not Zip bombs?

And what's more, did you write that 1 GB yourself, alone? Does it not contain things other than source code?
1GB source code sounds insane. It must take half an hour to compile at least!
Doesn't 1 GB amount to millions of lines of code?

@Catfish4
It's not holding as much information, though. It's stripped of comments and whitespace for one thing. It's also not reversible compression since you can't get the exact same source code through decompilation - usually you can't even get functioning source code. Saying an executable contains as much information as the source code is like saying an MD5 hash of a file contains as much information as the whole file.

@htirwin
1 GB is a billion characters assuming UTF-8 encoding; with an average of 100 characters per line that'd be 10 MLOC, so yeah. That's about the size of the Linux kernel, except Linux's source code isn't 1 GiB IIRC so I don't know.
Last edited on
closed account (N36fSL3A)
I'm sure it's just riddled with comments. Anti-Viruses seem to be very complicated.

*you still didn't answer my question*
I can't imagine one person writing that much, code comments or anything.
closed account (N36fSL3A)
I guess so...

The OP wrote:
The AV project was programmed for around 10 months, it was programmed in VS2012 Ultimate.
Much for 10 months... how much time did he dedicate?
Last edited on
Yeah I must have had a brainfart and didn't realize how much code 1 GB would actually be. That is pretty huge.

closed account (G309216C)
Hi,

Well guys, as I said if you don't believe it it's fine, it is up to you. Next I had holidays and trust me for around 13 hour including lunch and other activities I was coding this.

Next heuristic alogrithms are not very complicated buddy, it is matter of using "major" points of a Malware for example use of functions use as using NtUnmapViewOfSection() function or injecting into trusted processes without having digital signature can be a big sign of a Malware, and removing it is simple , destroy all threads of the process which is present in remote processes then call ZwTerminateProcess from kernel using a device driver, next then ones the process is terminated, before that get it's File location then we can disable all of its ACL's and DACL's using a ACE then when all of its objects are terminated or partially destroyed we can begin
then it will add a PAGE_NOACCESS flag to KiFastSystemCall and to X86SwitchTo64BitMode which means no functions can be used, therefore the Malware is nothing after that it will repeat the same procedure. then comes stage 2.

Network blocking, what we do is use the specialty of NDIS drivers to return 0, for network functions which the Malware uses for example we need to block LSP related functions which means send() and recv() won't work then we can return 0 from all Wininet functions.
Then is Stage 3, registry destruction and complete removal procedure:

remove all registry keys which have the file name mentioned, this would make sure all the persistence is gone then we need to also perform a corrupt the Malware via simply adding un-needed bits and remove few bits from the file such as the start the end and random positions of the middle of the file. Next we can delete the file before that just clear the whole Malware(s) data then delete it that way it is deemed useless.
Then after removal we simply add MD5 hash as well to a file, after few 10's build up, we can send it to a server via FTP transfer protocol then other AV's can check and cross-reference it back and fourth as well, therefore we also use heuristics to detect malware.
Last edited on
closed account (3qX21hU5)
Well guys, as I said if you don't believe it it's fine, it is up to you. Next I had holidays and trust me for around 13 hour including lunch and other activities I was coding this.


Wells lets break it down to the numbers.

Lets say you have a 60 wpm typing speed which is above average. The average word is probably like 4.5 characters so that would be 270 characters give or take a minute. And yes I know programming is different then typing normal words but if anything it just makes it harder and slowing so bear with me ;p

So lets say you program for 24 hours a day every day for lets say 1 year.

270 a minute * 60 minutes = 16,200 characters per hour.

16,200 characters per hour * 24 hours = 388,000 characters per day.

388,000 characters per day * 365 days = 141,912,000 characters per year.

So it is physically impossible to program a 1 billion characters (Or 1 gb) program in 10 months by yourself or even with 10 people or even 50 people.

This is if the 1 billion characters per 1GB holds correct which on that I am not sure but am taking chrisname's word on it.
Last edited on
closed account (N36fSL3A)
Maybe he holds down enter a lot?

And 13 hours a day is kinda much...
closed account (G309216C)
Well, I never said it was 1 billion lines it is 721,181 lines, the reason for this is becuase of debugger's, tools I need to use for better tracing.

Next you do know planning algorithms for these type of projects are incredibly complex, and trust me if a bug occurs it would be too hard to locate it, trust me.

Lumpkin first, have you ever worked on large projects, ask others here trust me they would know, just stick to studying for school. first of all you may not know but it is quite hard and next if I ask you a simple question which may have appeared in my project I bet you cash that you would not be able to solve it.
Last edited on
Pure text [EDIT]Assuming common English thank you, Lumpkin[/EDIT]characters are 1 byte per character. There are 1,073,741,824 bytes in a gigabyte. So yeah Zereo that's a pretty accurate estimation.

Sorry, I just can't make myself buy this.

Also, am I the only one that sometimes feels like SpaceWorm is stitching together random Windows API function names in somewhat coherent sentences? Someone with more experience with the Windows API should pitch in.

But yeah, like, power to you if you actually did this. I just won't be taking part, the evidence is stacking up against you :p
Last edited on
closed account (G309216C)
Well, as Thumper said someone can talk to me about these stuff and I will discuss about it all day, I can talk about it non-stop trust me.

Next the function name I said above is used by Duqu: NtUnmapViewOfSection well it uses ZwUnmapViewOfSection() but it is close enough for a example.
Just a KiFastSystemCall transfer difference.
Last edited on
closed account (N36fSL3A)
Actually, some Chinese characters take up multiple bytes ;)

FINALLY CORRECTED YOU :D
Somehow his random function names are relative to each other.
ZwUnmapViewOfSection is related to the kernelmode.
Nt^... is related to the usermode.
And KiFastSystemCall is related to linking kernelmode and usermode together.

That's what I understood by googling.
I didn't know KiFastSystemCall, but I knew Zw/NtUnmapViewOfSection already, and that Zw* is kernel, where Nt* is user.
closed account (G309216C)
EssGeEich, the both functions can be hooked in user-mode together without needing to hook them separately, because they both lie in the same address in memory, although both are still in Usermode so really we are not subverting the Windows Kernel.

To be more detailed, the ntdll.dll's functions in fact lay in same address in all process's so we can just hook them and in the callback mechanism, we can easily have a variable with the specific address for the ntdll.dll single export or a system call stub export them we can just create a stub of the original function and use that as a real-return value thus creating a successful trampoline based hook.

Next, by the looks of it EssGeEich, understands Windows API. So why not pitch in @EssGeEich, because I am not remotely worried about this because I know, that what I am telling is true.

I am using ZwUnmapViewOfSection function because some of the more high-end malwares use separate code injection method rather than using CreateRemoteThread and WriteProcessMemory because AV solutions don't really take them very seriously (well now they do because of Duqu and other copy cats of the Malware).

But the real trick of the trade to bypass any AV's proactive defense is to exploit the design of less sketchy functions, this way AV's will find it difficult to detect or even flag them because it uses less sketchy functions. Next trick is that AV bypasses don't happen because of a code but it is more or do's and don'ts, and successfully using these tricks could create one of the most successful Malwares.
You may want to be sure the virus itself doesn't hook those functions themself?
Also a virus could lie in a VirtualAlloc allocated space (I myself have been able to write raw ASM bytecode to a VirtualAlloc allocated space, and been able to run without exceptions with a simple "call". I guess VirtualAlloc is internally used by *MapViewOfSection)
Not much to say about this as I'm not a virus expert, just giving out some infos.
closed account (G309216C)
Hi,

Obviously there is something we can do about it, look say that the Virus hooks ZwMapViewOfSection. The first 5 would be like this:

jmp callbackAddress
...

Obviously there is one instruction because a jmp is 5 bytes in size. Therefore if the process calls the function (ZwMapViewOfSection) the function would be redirected to callbackAddress. This means that the callback will handle all the calls made by the processes.

So we can easily unhook it by simple changing the callbackAddress to our address. That way we have redirected\swapped our hooks. Then just as a precaution we can put VirtualProtect the callbackAddress with a NO_ACCESS flag this would mean that even if it is called it will create a Access Violation. No malware would even notice that. All they can do is to create a new callback but that is impossible to do during-runtime as that's a compiler's job expect they can do runtime-code-patching but majority will try but we can always change it back and also VirtualProtect that callback so after few loops of hooking-and-unhooking the whole process space of the Malware would be flagged with NO_ACCESS thus preventing it to be able to perform anything related to runtime-code-patching this would mean we can re-hook the function and the Malware will be helpless, even if the Malware tries our trick on us we un just call VirtualProtect and unprotect the memory again. Simple. BUT:

We really do not even need to do all that but, I do it just in case but the easier thing would be to simple put a protection around the callback address and it would crash the virus process. But I don't do that because it is not very professional as we do not want process crashing information coming on the desktop.

Besides we do not even need to do that because I have already hooked KiFastSystemCall and X86SwitchTo64BitMode so we are literally at the borders of Ring3 and Ring2 and malwares tend to hook single exports of ntdll.dll whereas we hijacked the whole Ring3 mode itself so we have 1/3 of Computer control and we also have ring0 as well this means we have complete hook on the system.

Next we have a MBR module meaning it is impossible for them to remove us even a other Malware cannot load a boot-loader because we have hidden the disk sector (sector 0) therefore they cannot load a Boot-loader. This prevents Bootkits from installing. This prevents the whole system compromise from boot-sector and ring0 therefore the only way is to go is Ring3 and even in Ring3 we have hooked the whole Ring3 so technically we can see everything with the smallest detail about anything we want to know.

So it is all about 1 algorithm (heuristics) and I am improving it as we speak.
Last edited on
If I may ask: what type of heuristics algorithm and techniques are you employing?
Pages: 1... 34567... 10