{
	"id": "2b4d7348-3b37-4899-a7e0-fd77f1902290",
	"created_at": "2026-05-06T02:02:42.884734Z",
	"updated_at": "2026-05-06T02:03:52.658659Z",
	"deleted_at": null,
	"sha1_hash": "5de32f7ec6e651e19b7875215ab6fbce0ab014d5",
	"title": "WannaCry Malware Analysis - How YOU Could have Saved the World ꩜",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 239527,
	"plain_text": "WannaCry Malware Analysis - How YOU Could have Saved the\r\nWorld ꩜\r\nPublished: 2026-04-19 · Archived: 2026-05-06 02:00:47 UTC\r\nSome details\r\nEveryone knows and has heard about the WannaCry ransomware. One of the biggests and most well known\r\nattacks to ever happen in cybersecurity, the range was so big that even people outside of the cybersecurity\r\ncommunity knew about it.\r\nWannaCry? :’(\r\nIf somehow you were the first analyst to stumble upon WannaCry. You could have stopped this attack with just a\r\nlittle bit of experience on Reverse Engineering/Malware Analysis.\r\nAfter looking for a while for the “original” WannaCry file I found this sample on MalwareBazaar. I verified some\r\nof the strings and function calls to make sure they match with this article that does some analysis on WannaCry.\r\nThis same article was mentioned by MalwareTech himself (Marcus Hutchins) on his now famous blog entry, in\r\ncase you don’t know who he is, he is the guy who stopped WannaCry.\r\n1\r\n2\r\n3\r\n4\r\n5\r\nSHA256 hash: 24d004a104d4d54034dbcffc2a4b19a11f39008a575aa614ea04703480b1022c\r\nSHA1 hash: e889544aff85ffaf8b0d0da705105dee7c97fe26\r\nMD5 hash: db349b97c37d22f5ea1d1841e3c89eb4\r\nhumanhash: berlin-angel-beer-quebec\r\nFile name: invoice_greenanimals.pdf.exe\r\nIt was a little bit hard to find the original file due to the big amount of variants that came after this attack, multiple\r\nvariants were distributed using a different domain as a killswitch and after those were useless they deleted the\r\nkillswitch from the file.\r\nAfter opening the file using Binary Ninja you will be located at 0x409a16 or _start() . This is just a normal\r\nlooking start of a C++ file. This function just tries to initialize the program correctly in a Windows environment.\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 1 of 11\n\nBut we can also see at the very end of the a function that I renamed to main() , this is the main logic behind the\r\nWannacry ransomware. This function is located at address 0x408140 .\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 2 of 11\n\nNow, if you don’t have any experience on reverse engineering you might think this is something hard or\r\nimpossible. Even if you have some experience doing programming, assembly code looks really weird. It doesn’t\r\nmatter if you don’t understand assembly or even if you have very little experience in programming, you can\r\nunderstand the graph in the photo. But first let’s examine this on detail.\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 3 of 11\n\nThis first instructions is just used to copy the URL\r\nhXXp://www[.]iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea[.]com into a local variable that will be used later\r\non the function.\r\nInternetOpenA - Get those Protocols\r\nThe next set of instructions are just a call to a the function InternetOpenA . This is an API Windows function that\r\ncan be used by multiple programs. The push instruction is used to send the parameters that the function needs to\r\nwork, here we have 5 push instructions, which means we have 5 parameters.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n00408171 push eax {var_5c} {0x0}\r\n00408172 push eax {var_60} {0x0}\r\n00408173 push eax {var_64} {0x0}\r\n00408174 push 0x1 {var_68}\r\n00408176 push eax {var_6c} {0x0}\r\nIf we search for the function InternetOpenA we can find the official Microsoft documentation for the function.\r\n1\r\n2\r\n3\r\n4\r\n5\r\nHINTERNET InternetOpenA(\r\n [in] LPCSTR lpszAgent,\r\n [in] DWORD dwAccessType,\r\n [in] LPCSTR lpszProxy,\r\n [in] LPCSTR lpszProxyBypass,\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 4 of 11\n\n6\r\n7\r\n [in] DWORD dwFlags\r\n);\r\nIn that same page we can find what each parameter is used for, and a summary of what the function does. From\r\nthe Microsoft documentation page:\r\nInitializes an application’s use of the WinINet functions.\r\nIf we search what WinINet means we can find the following explanation, I got this from the official Microsoft\r\ndocumentation:\r\nThe Windows Internet (WinINet) application programming interface (API) enables your application to\r\ninteract with FTP and HTTP protocols to access Internet resources. As standards evolve, these functions\r\nhandle the changes in underlying protocols, enabling them to maintain consistent behavior.\r\nAfter enabling the interaction with certain protocols to access Internet resources, the next step is to use that new\r\nresource to connect to the previous URL we saw.\r\nInternetOpenUrlA - Is this thing on?\r\nThe next function is InternetOpenUrlA.\r\nIn the documentation we can see the following:\r\nOpens a resource specified by a complete FTP or HTTP URL.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\nHINTERNET InternetOpenUrlA(\r\n[in] HINTERNET hInternet,\r\n[in] LPCSTR lpszUrl,\r\n[in] LPCSTR lpszHeaders,\r\n[in] DWORD dwHeadersLength,\r\n[in] DWORD dwFlags,\r\n[in] DWORD_PTR dwContext\r\n);\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 5 of 11\n\nIn the screenshot we saw previously we saw some interesting parameters being used to call the function.\r\nFirst we see these instructions (I skipped a few instructions that were not relevant):\r\n1\r\n2\r\n3\r\n4\r\n5\r\ncall dword [InternetOpenA]\r\nmov esi, eax\r\n...\r\npush esi\r\ncall dword [InternetOpenUrlA]\r\nWe have to know that after we call a function the return value or the result of that action is stored in eax . So\r\nafter a call instruction the return value is in eax , that’s why the next instruction mov esi, eax is used. After\r\nwe copy that to esi it is pushed to be used by call dword [InternetOpenUrlA] as a parameter.\r\n1. Call InternetOpenA\r\n2. Create a way for the program to have connection capabilities\r\n3. Use return value as a parameter to call InternetOpenUrlA\r\nWe also can see another push instruction where it uses the value 0x84000000 . This is a flag value, these are\r\nvalues that are used to turn on options. In this case we can search for the API Flag documentation for Wininet.h .\r\nFrom that website I got this:\r\nINTERNET_FLAG_RELOAD 0x80000000 Forces a download of the requested file, object, or\r\ndirectory listing from the origin server, not from the cache. The FtpFindFirstFile, FtpGetFile,\r\nFtpOpenFile, FtpPutFile, HttpOpenRequest, and InternetOpenUrl functions use this flag.\r\nINTERNET_FLAG_NO_CACHE_WRITE 0x04000000 Does not add the returned entity to the cache.\r\nThis flag is used by , HttpOpenRequest, and InternetOpenUrl.\r\nI can just add these values and it gives me 0x84000000 . This means that it uses both of these functions, you can\r\nsometimes watch these options like this:\r\n1 INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE\r\nThis means that it will always get the newest version of the website and it will not save the cache of that website\r\nto make sure the information is always up to date.\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 6 of 11\n\nSummary\r\nThis just creates a connection with Windows API to make sure the malware can use Internet capabilities of the\r\nsystem and then tries to access the domain hXXp://www[.]iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea[.]com .\r\nDepending on the result of these requests the malware is going to choose the next instructions that will be\r\nexecuted.\r\nThe branches\r\nSOo0oOo no website?\r\nAs I mentioned before this is were the most important decision is taken. What happens after we call the function\r\nInternetOpenUrlA to connect to the website?\r\nBased on the official Microsoft documentation:\r\nReturns a valid handle to the URL if the connection is successfully established, or NULL if the\r\nconnection fails.\r\nNULL is just a representation of the absense of a value or a reference. This is not the same as zero. In assembly\r\nlanguage NULL is represented by the value zero 0x0 .\r\nSo, if the function call to InternetOpenUrlA is not able to successfully establish a connection to the domain it\r\nwill return NULL or 0x0 .\r\nNow that value is stored in eax . We use a mov to store the value on the register edi . Then it does a\r\ncomparison with test .\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 7 of 11\n\n1\r\n2\r\n3\r\n4\r\ncall dword [InternetOpenUrlA]\r\nmov edi, eax\r\n...\r\ntest edi, edi\r\nThe test instruction is an AND operation. It takes the value 0x0 and then it uses this little table to get the\r\nresult. If we do an 0x0 AND 0x0 it will result on 0x0 .\r\ntest affects the Zero Flag (ZF) . If the result of the operation is zero, then it sets the flag to ZF = 1 . The\r\ninstruction JNE (Jump if not Equal) and JNZ (Jump if not Zero) are the alternate representations of the same\r\ninstruction.\r\nZF = 1 (Set): The result of the operation was zero.\r\nZF = 0 (Cleared): The result of the operation was non-zero.\r\nBoth JNE and JNZ execute the same machine code operation, jumping only when the Zero Flag is equal to\r\n1 .\r\n1\r\n2\r\ntest edi, edi ; NULL AND NULL = 0, sets ZF=1\r\njne 0x4081bc ; jump ONLY if ZF=0 (not zero)\r\nIf we are not able to connect to the domain then the flag is ZF=1 , meaning we will jump to this block:\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 8 of 11\n\nIt’s a very short block of code, it makes some calls to esi , at this time esi is holding the function\r\nInternetCloseHandle . It closes the connection and then calls a function I renamed to mw_ransom_start , this is\r\npretty self explanatory, I already did a quick analysis on that specific function to know what it does, but based on\r\nthe call to another function we can induce that this is most likely the infection function that will trigger the\r\nransomware.\r\nIt’s alive!!!\r\nIf the connection to the domain is succesful then the value will be a non zero value, if we use the table mentioned\r\nbefore the result of the AND operation will be a non zero value. Meaning that it will jump to 0x4081bc .\r\nThese instructions are pretty simple as well, it just calls the same function that is stored in esi which is once\r\nagain InternetCloseHandle . The whole block of code is made up of clean up instructions and doesn’t do\r\nanything meaningful and then it returns, which in other words means that the program closes itself.\r\nThanks to this analysis we know that the result of a connection to a certain domain will determine if the malware\r\ncloses itself without doing anything harmful to the victim’s computer.\r\nJust watch the little graph\r\nIs there a faster and easier way to get the same result? Yes, just watch the graph, you can notice easily that there\r\nare two different branches, meaning that a decision will be taken.\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 9 of 11\n\n1. See the branches from a decision at the very end of the function\r\n2. Notice that the left branch just closes the program without any suspicious function calls\r\n3. See the function call to InternetOpenUrlA and the suspicious URL\r\n4. Look for the value edi that is used by test . This is just a simple ‘if’\r\n5. mov edi, eax after the call to InternetOpenUrlA\r\n6. Notice that the execution of the malware depends on the result of the InternetOpenUrlA\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 10 of 11\n\nConclusion\r\nThis could have been done by you. You just had to watch the graph, notice the branch and just know what an if\r\nstatement is, search for some API that are well documented and use logic to know that the URL is used to\r\ndetermine the execution of the malware.\r\nSource: https://zanezhub.github.io/posts/WannaCry/\r\nhttps://zanezhub.github.io/posts/WannaCry/\r\nPage 11 of 11",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://zanezhub.github.io/posts/WannaCry/"
	],
	"report_names": [
		"WannaCry"
	],
	"threat_actors": [],
	"ts_created_at": 1778032962,
	"ts_updated_at": 1778033032,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/5de32f7ec6e651e19b7875215ab6fbce0ab014d5.pdf",
		"text": "https://archive.orkl.eu/5de32f7ec6e651e19b7875215ab6fbce0ab014d5.txt",
		"img": "https://archive.orkl.eu/5de32f7ec6e651e19b7875215ab6fbce0ab014d5.jpg"
	}
}