# MalwareBytes internals (incomplete)

This write up won't be nearly as technical or in-depth as I'd like. Initially when I decided to begin poking MalwareBytes with a stick my reasoning was pure curiosity. I don't have any reason really to try to reverse engineer MalwareBytes.

I initially played with the idea of developing a proof-of-concept malware payload which would be custom tailored to MalwareBytes evasion. As you'll see as you read this I've found some potential attack vectors. However, as time progressed I kind of just got bored with reversing MalwareBytes. I found some really cool stuff, I have an appreciation for MalwareBytes (and anti-malware products in general, actually), but I no longer possess the motivation to continue reviewing it.

I hope by sharing this you'll decide to review it yourself, or maybe you'll appreciate what I've written, or maybe you'll feel more compelled than I am to try to develop a custom malware payload for it.... or maybe you won't do any of this and you'll look at cat pictures on the internet. That is cool too.

I'd also like to note I have not reviewed MalwareBytes in totality. It is a big application with lots of moving parts. I don't want to spend the next three weeks poking this thing with a stick.

***

MalwareBytes has a bunch of programs. It has a bunch of DLLs. Some of the DLLs are from MalwareBytes (they're signed), some DLLs are external libraries it's dependent on (such as 7z DLLs, or Microsoft.NET DLLs). These DLLs are there to ensure they're not missing from the machine. Their presence isn't really indicative anything. It does however illustrate MalwareBytes needs 7z for stuff.

The main MalwareBytes executable (the one you see when you actually run the program) is written using the .NET framework. I am going to faithfully assume it is C#.NET, I'm skeptical they would use VB.NET. Regardless, when using ILspy it all turns into the same thing, so whatever.

The main MalwareBytes executable is a .NET loader which then loads the actual MalwareBytes UI, and all the fancy bells and whistles. It is MalwareBytes.dll.

tl;dr MalwareBytes.exe is just a loader for MalwareBytes.dll.&#x20;

```
MalwareBytes.exe
  └── CLR startup
        └── Load Assembly("MalwareBytes.dll")
              └── Invoke Main()
```

This isn't uncommon. Microsoft has a whole thing on it here: <https://learn.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting>

As you can see, it's a big ol' son-of-a-gun. It has a lot of moving parts. Most of it revolves around the UI, the remaining is interoperability with the low-level components which actually do the anti-malware stuff.

<figure><img src="https://1909493350-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMMhrryVZFTw609ivOju%2Fuploads%2Fzu7mOQFPHU1wJT1LFaJK%2F1.png?alt=media&#x26;token=09d2d7f9-d65f-4840-bb5a-2af0d8a1464c" alt=""><figcaption></figcaption></figure>

Funnily enough however, inside of these binaries (Mbam.UI.Data) contains the .NET code responsible for communicating with a database on the machine which contains user-mode settings and some other stuff. When you peek inside of that file you find the hardcoded password to the user-mode database located in %LOCALAPPDATA%

```
+-------------------------------+
|        MalwareBytes.exe       |
|  (bootstrapper / launcher)    |
+---------------+---------------+
                |
                | loads
                v
+-------------------------------+
|        MalwareBytes.dll       |
|   (core app / main logic)     |
+---------------+---------------+
                |
                | uses / calls into
                v
+-----------------------------------------------+
|               MbamUI.Data.dll                  |
|     (data layer / EF Core + DbContext)         |
+---------------+-------------------------------+
                |
                | EF Core provider:
                | Microsoft.Data.Sqlite
                | builds connection string
                v
+-------------------------------+
|             SQLite            |
|   (via Microsoft.Data.Sqlite) |
+---------------+---------------+
                |
                | opens
                v
+--------------------------------------------------------------+
|  %LOCALAPPDATA%\...\data.db                                  |
|                                                              |
|  (local SQLite file; encrypted)                               |
|                                                              |
|  password: VGhhbmtZb3VGb3JDaG9vc2luZ01hbHdhcmVieXRlcw          |
+--------------------------------------------------------------+

```

<figure><img src="https://1909493350-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMMhrryVZFTw609ivOju%2Fuploads%2Fv8RMNrj84rjJMuTGsUJX%2F2.png?alt=media&#x26;token=d04c490f-6ca3-45fe-860e-51443b70ce6d" alt=""><figcaption></figcaption></figure>

It is very silly. "VGhhbmtZb3VGb3JDaG9vc2luZ01hbHdhcmVieXRlcw" is Base64 encoded. When decoded is transforms into "ThankYouForChoosingMalwarebytes". That is a very cute Easter egg.

***

data.db, located in %LOCALAPPDATA% can viewed regularly using DB Browser (SQLCipher). This is required because this is password protected and requires authentication.

<figure><img src="https://1909493350-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMMhrryVZFTw609ivOju%2Fuploads%2FrjgxycTMS3uTnJNVtMsU%2F3.png?alt=media&#x26;token=c11d3a53-2f84-4025-9233-2e71be987914" alt=""><figcaption></figcaption></figure>

This is another standard user-mode database. This database stores user-mode configurations, alerts, blah blah blah. It should be noted however that, because the password is hardcoded, there is a potential abuse vector present. Security researcher [miltinhoc](https://x.com/miltinh0c) noted it is possible to change the password to data.db. When the password to the database is modified the entire application implodes into itself. Neat.

***

The actual detection logic for MalwareBytes comes from it's kernel-mode components. It has a few. [The main one is mbam.sys](https://learn.microsoft.com/en-us/windows-hardware/drivers/ifs/allocated-altitudes#320000---329998-fsfilter-anti-virus). mbam.sys (MalwareBytes Anti-Malware?) is their [minifilter](https://learn.microsoft.com/en-us/windows-hardware/drivers/ifs/about-file-system-filter-drivers) which does some heavy lifting for detecting malware. They have a bunch of other kernel-mode minifilters (as you can see from the attached link). I have not really dug into those yet. I didn't even have most of those present on my virtual machine. Some of those kernel-mode components are probably from other products, maybe, I don't know.

mbam.sys communicates, in some capacity I still haven't identified, with a proprietary data format MalwareBytes uses. All of their malware detection logic (YARA rules, or whatever) is stored inside of %PROGRAMDATA%\Malwarebytes\MBAMService\rules.mbdb

I am going to take an educated guess that "mbdb" stands for MalwareBytes Database.

I began attempting to reverse engineer their mbdb file format, but I began screaming and throwing things out my window. I dislike reverse engineering custom file formats. It is the work of the devil (I'm being hyperbolic for comedic effect, relax).

Their mbdb is "delimited" (using that word extremely liberally) with special characters (in actuality hex). It is "o|". It acts as the root identifier for their database. I unironically began using AI slop to try to figure out what the hell is going on. I wasn't going to spend hour Googling to try to identify patterns in the file.

Using AI slop and janky Python code, I was able to begin making a dent in their custom file format, but it was still too much effort for me.

```
o|   (outer/root container for the file)
|
|-- w| @0x000044  size=68
|-- y| @0x0000CC  size=68
|-- E| @0x0005D4  size=4
|
|-- 8| @0x017D8C  size=3,213,388
|    |
|    |-- E| @0x018198  size=32
|    |-- E| @0x023530  size=4
|    |-- E| @0x040700  size=32
|    |-- 9| @0x040948  size=32
|    |-- E| @0x0459CC  size=32
|    |-- D| @0x07C718  size=32
|    |-- E| @0x08C5D8  size=64
|    |-- E| @0x0AFDA4  size=4
|    |-- D| @0x0CB940  size=32
|    |-- E| @0x0CEEF8  size=4
|    |-- 9| @0x0D8E48  size=32
|    |-- E| @0x109DA4  size=32
|    |-- E| @0x12BD04  size=32
|    |-- 8| @0x1552D4  size=64
|    |-- E| @0x15E650  size=32
|    |-- E| @0x182C60  size=32
|    |-- 9| @0x183148  size=32
|    |-- E| @0x19E3E8  size=32
|    |-- D| @0x1B091C  size=32
|    |-- 8| @0x1CF10C  size=32
|    |-- 8| @0x1F2844  size=32
|    |-- D| @0x1F3D04  size=32
|    |-- 8| @0x21AC78  size=32
|    |-- 9| @0x21AF20  size=32
|    |-- E| @0x22F628  size=2
|    |-- 8| @0x230656  size=224
|    |-- 9| @0x23B266  size=32
|    |-- D| @0x2401B6  size=240
|    |-- 8| @0x241B8E  size=32
|    |-- E| @0x251E72  size=2
|    |-- E| @0x25EFFC  size=32
|    |-- 8| @0x260648  size=32
|    |-- D| @0x28B54C  size=32
|    |-- 8| @0x29A45C  size=32
|    |-- D| @0x2A713C  size=32
|    |-- 9| @0x2AAD04  size=32
|    |-- 8| @0x2B4128  size=32
|    |-- E| @0x2B5338  size=2
|    |-- E| @0x2DBA4E  size=32
|    |-- 8| @0x2F7A8A  size=64
|    |-- D| @0x30885E  size=32
|    |-- D| @0x310B16  size=32
|
|-- 8| @0x33ACBC  size=32
|-- 9| @0x33F174  size=64
|
|-- D| @0x3427E0  size=4,551,749
|    |
|    |-- E| @0x36F91C  size=32
|    |
|    |-- m| @0x3811C8  size=359,533
|    |    |
|    |    |-- E| @0x387398  size=32
|    |    |-- D| @0x3893AC  size=32
|    |    |-- E| @0x38DCC8  size=32
|    |    |-- 9| @0x3978EC  size=134
|    |    |-- 9| @0x39CA6E  size=64
|    |    |-- 9| @0x3A20C2  size=32
|    |    |-- E| @0x3A4A62  size=2
|    |    |-- D| @0x3C312C  size=32
|    |    |-- 9| @0x3C4040  size=176
|    |    |-- 9| @0x3D7D74  size=32
|    |
|    |-- D| @0x3E4EB1  size=32
|    |-- E| @0x3E8F21  size=32
|    |-- D| @0x419A6D  size=32
|    |-- 8| @0x429F61  size=32
|    |
|    |-- D| @0x433655  size=3,211,570
|         |
|         |-- 9| @0x433B41  size=32
|         |-- D| @0x45C2E5  size=32
|         |-- E| @0x463B4D  size=2
|         |-- E| @0x474887  size=2
|         |-- E| @0x475B39  size=32
|         |-- 9| @0x4A66C9  size=32
|         |-- D| @0x4A69F9  size=32
|         |-- E| @0x4BADC1  size=32
|         |-- E| @0x4C0FA1  size=32
|         |-- 9| @0x4DC431  size=32
|         |-- 9| @0x4F0651  size=32
|         |-- 9| @0x518A3D  size=32
|         |-- 9| @0x51A595  size=32
|         |-- 8| @0x543D45  size=32
|         |-- E| @0x547AC9  size=64
|         |-- b| @0x57C6D1  size=68
|         |-- E| @0x57C735  size=32
|         |-- e| @0x57C759  size=445
|         |-- y| @0x57CF5A  size=68
|         |-- 8| @0x586B0E  size=32
|         |-- D| @0x59391E  size=32
|         |-- E| @0x5B938E  size=2
|         |-- E| @0x5C7DB0  size=16
|         |-- 9| @0x5E9E60  size=32
|         |-- D| @0x62A788  size=32
|         |-- 9| @0x62A9B0  size=32
|         |-- E| @0x655D10  size=32
|         |-- D| @0x679954  size=32
|         |-- 9| @0x67CBF0  size=32
|         |-- E| @0x686484  size=32
|         |-- 9| @0x68ECC8  size=32
|         |-- 9| @0x68EDD8  size=32
|         |-- E| @0x69F84C  size=2
|         |-- 8| @0x6B317A  size=32
|         |-- D| @0x6DB3DA  size=64
|         |-- T| @0x6FD616  size=162,700
|
|    |-- 8| @0x76C24B  size=64
|    |-- 8| @0x76D853  size=64
|    |-- E| @0x779A4B  size=2
|    |-- 9| @0x77B141  size=32
|    |-- D| @0x791045  size=32
|
|-- E| @0x7A2781  size=2
|
|-- E| @0x7A4E57  size=4,618,048
|    |
|    |-- 9| @0x7AD237  size=3,212,605
|         |
|         |-- 8| @0x7B2557  size=64
|         |-- D| @0x7B5E53  size=32
|         |-- 9| @0x7BF273  size=32
|         |-- D| @0x80496B  size=32
|         |-- E| @0x830E67  size=2
|         |-- 9| @0x83230D  size=32
|         |-- E| @0x8505E5  size=32
|         |-- 9| @0x858A1D  size=32
|         |-- D| @0x88AC51  size=32
|         |-- 9| @0x8941E1  size=32
|         |-- E| @0x8A60F9  size=2
|         |-- 9| @0x8A93B7  size=32
|         |-- E| @0x8ACEDB  size=32
|         |-- 8| @0x8AE8F7  size=32
|         |-- 8| @0x8CE833  size=32
|         |-- 8| @0x8D88A3  size=32
|         |-- 9| @0x8E3627  size=32
|         |-- 8| @0x8E7CC3  size=32
|         |-- D| @0x93724B  size=64
|         |-- E| @0x940657  size=32
|         |-- E| @0x94F5EB  size=2
|         |-- E| @0x94F9CD  size=2
|         |-- 8| @0x9940AF  size=24
|         |-- 9| @0x9B145B  size=32
|         |-- 8| @0x9B24FF  size=64
|         |-- 8| @0x9B25D7  size=64
|         |-- E| @0x9C8B4B  size=2
|         |-- D| @0x9D0729  size=32
|         |-- E| @0x9E5985  size=32
|         |-- 9| @0xA1C8AD  size=32
|         |-- 8| @0xA3D145  size=32
|         |-- E| @0xA4B5F1  size=2
|         |-- 8| @0xA78213  size=32
|         |-- D| @0xAA5D2F  size=32
|
|    |-- D| @0xACB99C  size=148
|    |-- D| @0xACEDD4  size=32
|    |-- 9| @0xADD534  size=32
|    |-- E| @0xAE6864  size=64
|    |-- E| @0xAE93BC  size=32
|    |-- E| @0xB07374  size=32
|    |-- E| @0xB08E44  size=32
|    |-- E| @0xB1EB70  size=64
|    |-- 8| @0xB34718  size=32
|    |-- D| @0xB7A124  size=32
|    |-- E| @0xB85994  size=32
|    |-- 9| @0xB992B0  size=32
|    |-- 9| @0xB99AF0  size=32
|    |-- E| @0xB99C44  size=32
|    |-- E| @0xB9D6BC  size=64
|    |-- 8| @0xB9DB84  size=32
|    |-- 8| @0xBA911C  size=32
|    |-- 9| @0xBD95CC  size=32
|    |-- 8| @0xBFB634  size=32
|    |-- 9| @0xBFE688  size=32
|
|-- D| @0xC0D95B  size=32
|-- D| @0xC0DD27  size=32
|-- 9| @0xC4045F  size=32
|-- E| @0xC5250F  size=64
|-- C| @0xC66B1B  size=22
|-- E| @0xC6ECC5  size=2
|-- D| @0xC77397  size=152
|-- 8| @0xC78C9B  size=256
|-- E| @0xC86207  size=32
|-- 9| @0xC9A00B  size=32
|-- E| @0xC9C073  size=32
|-- E| @0xCADA13  size=32
|-- 6| @0xCB04D7  size=250
|-- 9| @0xCB0A51  size=68
|-- A| @0xCB13E1  size=68
|-- C| @0xCB14D1  size=362
|-- F| @0xCB185B  size=685
|-- K| @0xCB1E18  size=225
|-- M| @0xCB1FE1  size=190
|-- O| @0xCB214B  size=290
|-- R| @0xCB2421  size=168
|-- T| @0xCB250D  size=284
|-- V| @0xCB2745  size=240
|-- i| @0xCB376D  size=104
|-- k| @0xCB3819  size=68
|-- m| @0xCB38A1  size=68

```

```
o|
 ├─ 8| (3.2MB) ── [many small nodes]
 ├─ D| (4.6MB)
 │   ├─ m| (360KB) ── [metadata-ish]
 │   └─ D| (3.2MB) ── [payload-ish, includes T| blob]
 └─ E| (4.6MB)
     └─ 9| (3.2MB) ── [more structure]

```

I was able to carve out 4 different tables (maybe?) but it's got all sorts of stuff going on.

<figure><img src="https://1909493350-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMMhrryVZFTw609ivOju%2Fuploads%2FePN3U6yAroFUTmkJWUzn%2F7.png?alt=media&#x26;token=27d2140d-4274-49ed-9968-76c516577baf" alt=""><figcaption></figcaption></figure>

MalwareBytes has invested a lot of time and energy into preserving their intellectual property of malware detection logic (YARA rules, probably). I eventually said, "fuck it, I don't give a shit" and gave up. My goal wasn't to steal their data, so I don't really care too much, but it is incredibly interesting seeing this custom file format.

**---WARNING INCOMPLETE NOTES---**

Here is my notes I'm saving for later. I briefly wrote about it on X here: <https://x.com/vxunderground/status/2012409833614406120>.

I still have to poke some stuff with a stick.&#x20;

```
                     (boot / driver load)
                           |
                           v
                  +------------------+
                  |   mbam.sys       |
                  | (kernel driver)  |
                  +------------------+
                           |
                           | 1) Register minifilter
                           v
          +-------------------------------------------+
          | FltRegisterFilter / FltStartFiltering     |
          |  -> sets PreOp / PostOp callback routines |
          +-------------------------------------------+
                           |
                           v
                   +---------------+
                   |  MiniFilter   |
                   |  Callbacks    |
                   +---------------+
                           |
                           | 2) File event: create/open/read/etc
                           v
        +---------------------------------------------------+
        |  PreOpCallback( FILE_OBJECT / path / process info )|
        +---------------------------------------------------+
                           |
                           | 3) Normalize + extract identity
                           |    (path, hash, signer, PID, etc.)
                           v
                 +---------------------------+
                 | Check against rules.mbdb  |
                 |  (local rules database)   |
                 +---------------------------+
                    |                    |
                    | match / allow      | not found / suspicious
                    |                    |
                    v                    v
          +-------------------+     +------------------------------+
          | Allow / passthru  |     | Escalate to behavior layer   |
          | (no extra action) |     | (needs user-mode hooks)      |
          +-------------------+     +------------------------------+
                                        |
                                        | 4) Ensure mbae.sys present
                                        v
                              +------------------+
                              |   mbae.sys       |
                              | (anti-exploit)   |
                              +------------------+
                                        |
                                        | 5) Inject / enable hooks
                                        |    for target process
                                        v
                 +------------------------------------------------+
                 | Process instrumentation (user-mode + kernel)    |
                 | - load protections / shims / DLL hooks          |
                 | - monitor calls / memory / exploit primitives   |
                 +------------------------------------------------+
                                        |
                                        v
                           +--------------------------+
                           | Decision / block / alert |
                           +--------------------------+

```

<figure><img src="https://1909493350-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgMMhrryVZFTw609ivOju%2Fuploads%2FgYczdI76P09XmzmubThd%2F5.png?alt=media&#x26;token=af298c51-d02d-49ac-b36e-347619b290d3" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://malwaresourcecode.com/home/my-projects/write-ups/malwarebytes-internals-incomplete.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
