{
	"id": "8f266e29-a72c-4c4b-899e-ead605d40dcd",
	"created_at": "2026-04-06T00:11:13.314824Z",
	"updated_at": "2026-04-10T03:21:04.934818Z",
	"deleted_at": null,
	"sha1_hash": "7d4345435ab0076744980c3f4e9e59b0af0cb749",
	"title": "VBA Stomping — Advanced Maldoc Techniques",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1691794,
	"plain_text": "VBA Stomping — Advanced Maldoc Techniques\r\nBy Carrie Roberts\r\nPublished: 2020-04-11 · Archived: 2026-04-05 17:15:57 UTC\r\nAuthors: Kirk Sayre (@bigmacjpg), Harold Ogden (@haroldogden) and Carrie Roberts (@OrOneEqualsOne)\r\nIntroduction\r\nThere are powerful malicious document (maldoc) generation techniques that are effective at bypassing anti-virus\r\ndetection. A technique which we refer to as VBA stomping was originally brought to our attention by Dr. Vesselin\r\nBontchev (see here). VBA stomping refers to destroying the VBA source code in a Microsoft Office document,\r\nleaving only a compiled version of the macro code known as p-code in the document file. Maldoc detection based\r\nonly on the VBA source code fails in this scenario. In this blog post we will demonstrate detailed examples of\r\nVBA stomping as well as introduce some additional techniques.\r\nVBA Stomping\r\nFirst, we will demonstrate VBA stomping on a simple, non-malicious macro. This document simply displays a\r\nmessage box with the text “ABC” when the document is opened. The VBA source code and resulting message box\r\nis shown below.\r\nNow we are interested in modifying the VBA source code shown above, while leaving the intermediate p-code\r\nunchanged. For the purposes of this blog post we will concentrate on the current .docx/.xlsx/.docm/.xlsm (Office\r\n2007+) format. However, the techniques discussed here can easily be applied to the older .doc/.xls format. In\r\nOffice 2007+ files the VBA source code and p-code is typically located in a file called vbaProject.bin. Note that\r\nthis is the default filename but it can be renamed. To manually modify this file, we need to first unzip the\r\ncompressed .docm/.xlsm file and then open vbaProject.bin file in a hex editor. In this example, we will change\r\n“ABC” to “XYZ”, but only within the VBA source code storage location, not the p-code section. The VBA source\r\ncode is stored in a compressed form which explains the unprintable or odd characters you see in the following\r\nimage.\r\nhttps://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278\r\nPage 1 of 9\n\nPress enter or click to view image in full size\r\nNow that we have manually edited the VBA source to change “ABC” to “XYZ”, we will open the document and\r\ninspect the VBA source code BEFORE the “Enable Content” button is clicked.\r\nThe document has been opened but macros are not enabled. Inspecting the macro in the code editor indicates that\r\na message box with the text “XYZ” will be displayed but this is not the case. In fact, as soon as the content is\r\nenabled, a message box showing “ABC” is displayed and the source code in the code editor is updated to match!\r\nhttps://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278\r\nPage 2 of 9\n\nWell, that surely was misleading. The source code said that “XYZ” was going to be displayed in the message box\r\nbut instead “ABC” was displayed. What is going on?\r\nAs Dr. Bontchev explains, the p-code stored in the document is what actually executes, as long as it is compatible\r\nwith the current VBA version on the system. In addition, what gets displayed in the macro editor (once content is\r\nenabled) is not the decompressed VBA source, but instead it is the decompiled p-code. Interesting!\r\nIf we open the document in a different version of Word (which uses a different VBA version) the p-code will not\r\nbe reusable. This will force the VBA source code to be decompressed and recompiled to p-code, resulting in the\r\ndisplay of “XYZ” in the message box. So now we have a single document, which on one version of Office\r\ndisplays “ABC”, but on another version displays “XYZ”.\r\nNote that this is an important caveat. A VBA stomped maldoc can only be executed using the same VBA\r\nversion used to create the document. This limitation can be addressed by doing reconnaissance on a target prior\r\nto maldoc generation to determine the appropriate Office version to use or by generating maldocs with multiple\r\nOffice versions and spraying them against the target.\r\nWhat is the effect of VBA stomping from a defensive standpoint? Maldoc detection is often based solely on the\r\nVBA source. Even many of the tools available for analyzing documents fail to identify the discrepancy between\r\nthe VBA source and the p-code. The analysis of the tampered document by the olevba script, by Philippe Lagadec,\r\nshows the decompressed source only and lacks the p-code detail.\r\nThe Python script oledump.py, by Didier Stevens, gives similar results unless run with the p-code dumper plugin.\r\nThe output in this case gives some indication that the p-code will result in a message box display of “ABC” as\r\nshown in the image below.\r\nhttps://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278\r\nPage 3 of 9\n\nDr. Bontchev released a Python script called pcodedmp.py for displaying p-code as shown in the image below.\r\nThe output has the added benefit of showing operation names instead of op-codes as above.\r\nInstead of just modifying the VBA source code, we could completely wipe it out (“stomp” it) by overwriting it\r\nwith zero’s or random bytes. The following screenshot shows how to do this manually in a hex editor.\r\nhttps://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278\r\nPage 4 of 9\n\nThe result in this case is a VBA editor that shows no macro code at all, yet the message box with the text “ABC”\r\nstill appears after enabling content. Now we re-run olevba on this file and no VBA source code is displayed and\r\nthe statement “No suspicious keyword or IOC found” is displayed instead of the table that previously highlighted\r\nour use of a suspicious keyword (AutoOpen).\r\nHow Big of a Problem Is This?\r\nWe will now dive a little deeper into the how Office uses the compressed VBA source code and p-code. This will\r\ncome into play later when we go over how to abuse Office functionality to easily modify maldocs to fool many\r\nAV scanners.\r\nGet Carrie Roberts’s stories in your inbox\r\nJoin Medium for free to get updates from this writer.\r\nRemember me for faster sign in\r\nOffice documents contain two places from which to pull the VBA, the compressed VBA source code and the p-code. The following table details which VBA data source is used when:\r\nPress enter or click to view image in full size\r\nhttps://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278\r\nPage 5 of 9\n\nFrom this table we see that if we have valid p-code, the compressed VBA source code is ignored when macros are\r\nenabled. All macro functionality is performed by running the p-code. As an attacker this tells us that we can\r\ncompletely ruin or modify the compressed VBA source code and still have our maldoc perform its desired task.\r\nReal World Example\r\nShowing that this works on a toy example is all well and good, but is this really a legitimate threat? Let’s take this\r\nto the next level by working with a known malicious document. In this case, we will start with a recent Emotet\r\nmaldoc that is currently detected as malicious by 36/59 vendors on Virus total.\r\nIf we take this document and simply stomp the VBA source code as described above, the detection rate goes down\r\nto 7 out of 58 anti-virus solutions!\r\nhttps://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278\r\nPage 6 of 9\n\nAs you can see, this creates a serious problem for network defenders. Even manual analysis of such documents\r\ncould be problematic. The obvious question at this point is “Can VBA stomping be performed automatically by a\r\ntool or do we always have to manually edit the Office document?” The answer to this question is yes, it certainly\r\nis possible to stomp VBA automatically with a tool. We have developed a POC utility to automatically stomp the\r\ncompressed VBA source code in any Office document (this was used to VBA stomp the example Emotet\r\ndocument and no, we will not be releasing this utility). Given how easy it is to automate VBA stomping this is a\r\nreal threat.\r\nMaking It Worse\r\nConsider the case where the maldoc is designed to close MS Word immediately after executing the malicious\r\npayload. In combination with VBA stomping, no offline VBA source extraction tools will display the VBA source\r\nand the VBA source will not even be displayed in the Office macro editor window until the macro is enabled. But\r\nenabling the macro causes Word to immediately exit without providing an opportunity to view the decompiled\r\nsource. While we have shown that the “assembly-like” p-code is extractable, the p-code is difficult to interpret and\r\ncannot be analyzed in the VBA debugger. In addition, the pcode only runs on a specific VBA version. For these\r\nreasons, access to the VBA source code would be a great benefit to the analyst. But how can this be done for such\r\na document?\r\nAfter some experimentation, we determined a simple solution to stop MS Word from executing any method as\r\nsoon as macros are enabled. Note that this solution works for Office 2007+ documents, additional research is\r\nbeing performed to address older document formats. The 2007+ solution is to delete the vbaData.xml file from the\r\n“word” directory of the .docm file as shown below (this is easily done with the 7-Zip program without having to\r\nmanually unzip and re-zip the document).\r\nhttps://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278\r\nPage 7 of 9\n\nThe document can now be opened and the content can be enabled, resulting in the display of the decompiled p-code in the VBA code editor but no code execution. This could be a life saver in the event that the malware author\r\nhas taken steps to prevent the analyst from having access to the VBA source code.\r\nAn interesting side effect of erasing vbaData.xml is that it causes MS Word to erroneously list no Macros in the\r\nMacros dialog (see image below).\r\nDetection\r\nWe have written an open source tool for detecting VBA stomping in Office documents called “VBA\r\nSeismograph”. This tool has been tested under Ubuntu 16.04 and detects differences between the declared\r\nhttps://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278\r\nPage 8 of 9\n\nfunction/variable names, string literals, and comment lines that appear in the compiled p-code and the VBA source\r\ncode of an Office document. The tool is available at https://github.com/kirk-sayre-work/VBASeismograph.\r\nConclusion\r\nIn this blog post we have demonstrated how the compressed VBA source code in an Office document can be\r\nmodified or destroyed to defeat AV scanning solutions and make manual analysis of maldocs more difficult.\r\nDefense against this technique involves detecting and flagging documents with valid p-code but invalid or missing\r\nVBA source code, or more generally, checking for discrepancies between the compressed VBA source code and\r\nthe decompiled p-code. At this point in time we are not aware of any commercial AV solutions that do this check,\r\nso this is a potential area where AV scanning solutions can improve.\r\nSee vbastomp.com for the most up to date information on VBA stomping.\r\nSource: https://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278\r\nhttps://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278\r\nPage 9 of 9",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://medium.com/walmartglobaltech/vba-stomping-advanced-maldoc-techniques-612c484ab278"
	],
	"report_names": [
		"vba-stomping-advanced-maldoc-techniques-612c484ab278"
	],
	"threat_actors": [],
	"ts_created_at": 1775434273,
	"ts_updated_at": 1775791264,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/7d4345435ab0076744980c3f4e9e59b0af0cb749.pdf",
		"text": "https://archive.orkl.eu/7d4345435ab0076744980c3f4e9e59b0af0cb749.txt",
		"img": "https://archive.orkl.eu/7d4345435ab0076744980c3f4e9e59b0af0cb749.jpg"
	}
}