Tag Archives: Memory Forensics

Notes on Linux Memory Analysis – LiME, Volatility and LKM’s

[The post below contains some notes I wrote about Linux memory forensics using LiME and Volatility to analyze a Red Hat 6.10 memory capture infected with Diaphormine and Reptile, two known Linux Kernel Module rootkits.]

Back in 2011, Joe Sylve, Lodovico, Marziale, Andrew Case, and Golden G. Richard published a research paper on acquiring and analyzing memory from Android devices “Acquisition and analysis of volatile memory from android devices” [1]. At Shmoocon 2012, Joy Sylve gave a presentation titled “Android Mind Reading: Memory Acquisition and Analysis with DMD and Volatility“[2]. This work was the precursor of Linux Memory Extractor aka LiME [3]. LiME is an open source tool, created by Joy Sylve, that allows incident responders, investigators and others to acquire a memory sample from a live Linux system.

Some years before, The Volatility Framework was developed based on the research that was done by AAron Walters and Nick Petroni on Volatools [4] and FATkit [5]. The first release of the Volatility Framework was released in 2007. In 2008 the volatility team won the DFRWS challenge [6] and the new features were added to Volatility 1.3.  At the moment, Volatility is a powerful, modular and feature rich framework that combines a number of tools to perform memory analysis. The framework is written in Python and allows plugins to be easily added in order to add features. Nowadays it is on version 2.6.1 and version 3 is due this month. It supports a variety of operating systems. To analyze memory captures from Linux systems, Andrew Case, in 2011 [7], introduced several techniques into the Volatility framework in order to analyze Linux memory samples. Since then, new plugins have been introduced and different kernel versions are supported. At the moment there are 69 Linux plugins available.

Worth to mention that Michael Hale Ligh, Andrew Case, Jamie Levy, AAron Walters wrote the book “The Art of Memory Forensics Detecting Malware and Threats in Windows, Linux, and Mac Memory” that was published by Wiley in 2014 and is a reference book in this subject.

LiME works by loading a kernel driver on the live system and dump the memory capture to disk or network. The only catch is that the loadable kernel module needs to be compiled for the exact version of the kernel of the target system. Volatility is then be able to interpret this memory capture, but it needs a profile that matches the system from where the memory was acquired. Building a Volatility profile is straightforward, but it requires kernel’s data structures and debug symbols obtained for the exact kernel version of the target system obtained using the dwardfump utility.  This means that if you want to acquire a memory capture from a system in an enterprise, the incident response team will need to transfer LiME and Volatility code to the system and compile it in order to create the required files. Sometimes the target system won’t have the necessary dependencies and additional packages will need to be installed such as compilers, DWARF libraries, ELF utilities, Kernel headers, etc. This is a sensible step from a forensic standpoint. Hal Pomeranz, experienced forensics professional, has a few comments about this on the readme file from his Linux Memory Grabber utility [8].

In an ideal world all the requirements necessary to have LiME kernel module and Volatility profile for all your Linux kernel versions will be done in advance. This can be done and should be done during the preparation phase [9] of your incident response process. This phase/step is when incident response team prepares and trains for an incident. One thing that can be done is creating LiME modules and Volaility profiles for the Kernel versions of the systems that are running in production. This can be done directly on the system or on a pre-production system. Of course, I can tell you that based on my experience, this hardly happens. Its more common the case when an incident happens i.e., an attacker used a Linux system in an enterprise environment as a staging environment or used it to achieve persistence or use it to pivot into other network segments, there are no LiME kernel modules or Volatility profiles for the compromised system. Yes, the incident response team acquires live response data or a forensic image of the disk but the acquisition of memory can aid the investigation efforts.

During enterprise incident response its common to come across the need to analyze commercial Linux systems such as Red Hat that are running business applications. In this article I will be looking at a RedHat Enterprise Linux Server release 6.10 with code name Santiago.

The following illustration shows the steps for compiling LiME on the target system. I start by checking the Kernel version following by installing the necessary dependencies on this particular system. The LiME package can be retrieved from GitHub and can be made available to the target system using removable media, a network file share, or by copying into the system. Compiling LiME is an easy step.

Next step is to run LiME with the insmod command. This step will acquire a memory sample in LiME format and in this case I also told LiME to produce a hash of the acquired memory sample. As an example the memory capture is written to disk but in a real incident is should be written to a network share, removable media sent via the network. Finally, you can remove the module with rmmod.

After that, we need a Volatility profile for the Linux kernel version we are dealing with. On this version of RedHat I could not find a RPM for Libdwarf that contained the Dwarf tools. I had to get the source code from GitHub and transfer it to the system and compile it. Then, with the dependencies met I could compile and make the dwarf module.

Finally, I acquired the system-map file and zipped it together with module.dwarf. This zip file needs to be placed in the volatility profiles folder or you can place it on a different folder and specify it in the command line.

Now that I have a profile for the Linux system that I can try different Volatility plugins. In this particular case I was interested in determining what I could observe when looking with Volatility on a memory capture from the system after it has been backdoored with publicly available rootkits. There are several Volatility plugins for Volatility that can help identifying rootkits [10]. Let’s review three that might help with rootkits that leverage Linux Kernel Modules..

The linux_check_modules plugin. This plugin will look for kernel loadable modules that are not listed under /proc/module but still appear under /sysfs/module and will show the discrepancies. There is also the linux_hidden_modules which will look at the kernel memory region where modules are allocated and scans for module structures. Modules appearing with this plugin might indicate they were released but still laying in memory or they are hiding.

The linux_check_syscall plugin. This plugin will check if the sys_call_table has been modified. It lists all syscall handler function pointers listed in the sys_call_table array and it compares them with the address specified in the Kernel Symbols Table. If they don’t match, the message hook will be displayed.

The linux_check_kernel_inline plugin. This plugin will detect inline hooking. Among other things it will check if the prologue of specific functions in the kernel contains assembly instructions like JMP, CALL or RET. A match will display a message about the function that is being hooked.

In terms of Rootkits that leverage Loadable Kernel Modules I will look into Diamorphine [11] and Reptile [12]. Essentially, infecting the Red Hat system with the rootkit and capture a memory sample.

Let’s start with Diamorphine. Written by Victor Mello is a kernel rootkit written in C that supports Linux Kernels 2.6.x/3.x/4.x. It can hide processes, files and directories. It works by hooking the sys_call_table, more specifically it hooks the kill, getdents and getdents64 syscall handler addresses, making them point to the Diaphormine code. After loading into memory, the LKM module won’t be visible in /proc/modules but is still visible under /sys/module.

The following illustration shows, as an example, the Reptile installation on a Red Hat 6.10 system. It also shows that after the insertion of the malicious module into the Kernel, it doesn’t appear under /proc/modules. There is also a step on hiding a PID referent to bash process.

Following the previous steps, another memory sample was captured, and I ran the linux_check_modules Volatility plugin. As we could see, the plugin was able to find the Reptile module because he was still visible under /sysfs/module. We could dump the module to disk using the linux_moddump (didn’t worked for me at the time I tried it) and perform additional analysis in case this was something we were uncertain about. In this case I just looked at the first bytes of the module using linux_volshell plugin. The Volshell plugin was created in 2008 by Brendan Dolan-Gavitt. Following ilustration shows the usage of VolShell to print out 128 bytes in ASCII and look for interesting strings.

The other plugin worth to run is linux_check_syscall, which in this case is able to detect three hooked syscalls. Syscall 62, 78 and 217 which we can match against the syscall table from the pristine system, by looking at /proc/kallsyms, and check that the number corresponds to sys_kill, sys_getdents and sys_getdents64, respectively. Following that, and from a analysis perspective, I could use VolShell on the pristine memory dump and also on the one that has Diaphormine LKM loaded. Then I could list a few bytes in Assembly to compare and understand how good and bad looks like. In the following picture, on the left side, you can see the good sys_kill function and on the left side the bad one. Basically the syscall handler address was modified to point to the Diaphormine code.

The other rootkit that is worth to look at is Reptile. It was written by Ighor Augusto and is a feature rich rootkit with features like port knocking. It is written in C and under the hood it uses the Khook framework. You can see the presentation “Linux Kernel Rootkits Advanced Techniques” from Ilya Matveychikov and Ighor Augusto that was given during H2HC 2018 [13] conference at São Paulo, Brasil where Reptile was released. Khook, among other things, instead of hooking the sys_call_table it uses a different technique that patches a function prologue with a JMP instruction. With the Volatility linux_check_syscal plugin we can’t detect this hooking technique since the syscall handler addresses have not been modified but it can be identified with linux_check_kernel_inline. Among other things, Reptile hooks fillonedir(), filldir(), filldir64(), compat_fillonedir(), compat_filldir(), compat_filldir64(), __d_lookup(). To hide processes, it hooks tgid_iter() and next_tgid(). To hide network connections, it hooks tcp4_seq_show and udp4_seq_show.

The following illustration shows, as an example, the Reptile installation on a Red Hat 6.10 system.

After compromising a system with Reptile and acquiring a memory capture, I executed the mentioned plugins. I started with linux_hidden_modules to look for LKM structures in the Kernel Memory. Volatility was able to find the Reptile LKM. Then we could dump the module to disk and perform additional static analysis.

The other plugin executed is linux_check_inline_kernel. It was able to detect several network related functions that were patched by the Reptile code. I didn’t had time to further investigate why the Hook Address is not shown but we can get futher details with Volshell.

The following picture shows a comparison of a good tcp4_seq_show function on the left side from a memory capture of a pristine system and, on the right, it shows the same function but as we could see it has been patched to jump (JMP) to the Reptile code.

Another function that is patched by Reptile code in order to hide directories is the filleonedir. Not sure why Volatility didn’t detected this but the plugin might be easily adjustable to perform further checks and detect it. On the image below, on the left side, I used Volshell to check the function prologue on a pristine system. On the right side, we can see how the patched function looks like.

That’s it for today. In this post I shared some notes on how to use different Volatility plugins to detect known Rootkits that leverage Linux Kernel Modules. The memory capture was obtained using LiME and and instructions were given on how to acquire the memory capture and create a Volatility profile. Nothing new but practice these kind of skills, share your experiences, get feedback, repeat the practice, and improve until you are satisfied with your performance. Have fun!

[1] http://www.dfir.org/research/android-memory-analysis-DI.pdf

[2] https://www.youtube.com/watch?v=oWkOyphlmM8

[3] https://github.com/504ensicsLabs/LiME

[4] https://www.blackhat.com/presentations/bh-dc-07/Walters/Paper/bh-dc-07-Walters-WP.pdf

[5] http://4tphi.net/fatkit/papers/fatkit_journal.pdf

[6] http://volatilesystems.blogspot.com/2008/08/pyflagvolatility-team-wins-dfrws.html

[7] http://dfir.org/research/omfw.pdf

[8] https://github.com/halpomeranz/lmg

[9] https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-61r2.pdf

[10] https://github.com/volatilityfoundation/volatility/wiki/Linux-Command-Reference

[11] https://github.com/m0nad/Diamorphine

[12] https://github.com/f0rb1dd3n/Reptile/

[13] https://github.com/h2hconference/2018/


SANS FOR526: Advanced Memory Forensics & Threat Detection

The Art of Memory Forensics Detecting Malware and Threats in Windows, Linux, and Mac Memory

Tagged , , , , , ,

Memory Forensics with Volatility on REMnux v5 – Part 2

Before we continue our hands-on memory forensics exercise, will be good to refresh some concepts on how memory management works on Windows 32 bits operating systems running on x86 architecture. Windows operating systems have a complex and sophisticated memory management system. In particular the way the mapping works between physical and virtual addresses is a great piece of engineering.  On 32 bits x86 machines, virtual addresses are 32 bits long which means each process has 4GB of virtual addressable space. In a simplified manner the 4GB of addressable space is divided into two 2GB partitions. One for user mode processes – Low 2GB (0x00000000 through 0x7FFFFFFF) -and another for the Kernel mode – High 2GB (0x80000000 through 0xFFFFFFFF). This default configuration could be changed in the Windows boot configuration data store (BCD) to accommodate 3GB for user mode.  When a process is created and a region of virtual address space is allocated – trough VirtualAlloc API – the memory manager creates a VAD (Virtual Address Descriptor) for it. The VAD is essentially a data structure that contains the various elements of the process virtual addresses organized in a balanced tree. Elements such as the base address, access protection, the size of the region, name of mapped files and others are defined on each VAD entry.  The Microsoft Windows Internals book goes over in great detail about it.

Fortunately, Brendan Dolan-Gavitt, back in 2007 created a series of plugins for The Volatility Framework to query, walk and perform forensic examinations of the VAD tree. His original paper is available here.

That being said the next step in our quest to find the malicious code. We will use these great plugins to look at the memory ranges that are accessible by the suspicious process virtual address space. This will allows us to look for hidden and injected code. Worth to mention that a great book with excellent resources and exercises about this matter is the Malware Analyst Cookbook from Michael Ligh et. al. Another great resource that also goes into great detailed and was published last year is the Art of Memory Forensics also from Michael Ligh and the Volatility team.  Both books mention that among other things the VAD  might be useful to find malicious code hiding in another process. Essentially, by looking at the memory ranges that have an access protection marked as executable specially with the  PAGE_EXECUTE_READWRITE protection. This suggest that a particular memory range might be concealing executable code. This has been demonstrated by Michael Ligh and was translated into a Volatility plugin named Malfind. This plugin, among other things, detects code that might have been injected into a process address space by looking at its access protections.  For this particular case Malfind does not produce results for the explorer.exe (PID 1872). Might be due to the fact that permissions can be applied at a further granularity level than the VAD node level.

Our next hope is to start looking at the different VAD attributes and mapped files of the VAD tree for this suspicious process using the Vadinfo plugin. The Vadinfo plugin goes into great detail displaying info about the process memory and the output might be vast. For the sake of brevity only the first entry is displayed in the following picture.


In this case the output of the Vadinfo plugin displays almost two hundred VAD nodes and its details. Because we are looking for specific IOCs that we found we want to further look into these memory regions. This is where the Vaddump plugin comes to great help. Vaddump is able to carve our each memory range specified on the VAD node and dump the data into a file.


Then we can do some command line kung-fu to look into those files. We can determine what kind of files we have in the folder and also look for the indicators we found previously when performing dynamic  analysis.  In this case we could observe that the string “topic.php” appears in five different occasions using the default strings command. In addition it appears once when running strings with a different encoding criteria – and this exactly matches the found IOC.


On a side note is interesting to see based on the file names the memory ranges that span the virtual address space from 0x00000000 to 0x7FFFFFFF. And you also could see that there is some groups of addresses more contiguous than others. This related on how the process memory layout looks like. The following image illustrates this layout on a x86 32bit Windows machine. This can be further visualized using VMMap tool from Mark Russinovich and available on the Sysinternals Suite.


Back to our analysis, one first step is to look across dumped data from the Vaddump plugin see if there is any interesting executables files. We observed that the previous search found several Windows PE32 files. Running again our loop to look for Windows PE32 files we see that it contains 81 executables. However, we also know the majority of them are DLL’s. Lets scan trough the files to determine which ones are not DLL’s. This gives good results because only two files matched our search.


Based on the two previous results we run again the Vadinfo plugin and looked deeper into those specific memory regions. The first memory region which starts at 0x01000000 contains normal attributes and a mapped file that matches the process name. The second memory regions which starts at 0x00090000 is  more interesting. Specially the node has the tag VadS. According to Michael Ligh and the Volatility Team this type of memory regions are strong candidates to have injected code.


Next step? run strings into this memory region to see what comes up and don’t forget to run strings with a different encoding criteria.

As you could see below, on the left side, we have a small set of the strings found on the memory region. This information gives great insight into the malware capabilities, gives further hints that can be used to identify the malware on other systems and can further help our analysis. On the right side you have a subset of the strings found using a different encoding criteria. This goes together with previous strings and  gives you even further insight into what the malware does, its capabilities and the worst it can do.


Security incident handlers might be satisfied with dynamic analysis performed on the malware because they can extract IOCs that might be used to identify the malware across the  defense systems and aid the  incident response actions. However, trough this exercise we gained intelligence about what the malware does by performing memory forensics. In addition, as malware evolves and avoids footprints in the hard drive the memory analysis will be needed to further understand the malware capabilities. This allows us to augment prevention controls and improve detection and response actions. Nonetheless, one might want to even go further  deep and not only determine what the malware does but also how.  That being said the next logical step would be to get the unpacked malware from memory and perform static analysis on the sample. Once again, Volatility Framework offers the capability of extracting PE files from memory. Then they can be loaded into a dissasembler and/or a debugger. To extract these files from memory there are a variety of plugins. We will use the dlldump plugin because it allows you to extract PE files from hidden or injected memory regions.

There are some caveats with the PE extraction plugins and there is a new sport around malware writers on how to manipulate PE files in memory or scramble the different sections so the malware analysts have a tougher time getting them. The Art of Memory Forensics and the The Rootkit Arsenal book goes into great detail into those aspects.


With the malware sample unpacked and extracted from memory we can now go in and perform static analysis … this is left for another post.

That’s it – During the first part we defined the  steps needed to acquire the RAM data for a VMware virtual machine before and after infection.  Then, we started our quest of malware hunting in memory. We did this by benchmarking both memory captures against each other and by applying the intelligence gained during the dynamic analysis. On the second part we went deeper into the fascinating world of memory forensics. We manage to find the injected malware in memory that was hidden in a VAD entry of the explorer.exe process address space. We got great intel about the malware capabilities by looking at strings on memory regions and finally we extracted the hidden PE file. All this was performed  using the incredible Volatility Framework that does a superb job removing all the complex memory details from the investigation.


Malware sample used in this exercise:

remnux@remnux:~/Desktop$ pehash torrentlocker.exe
file:             torrentlocker.exe
md5:              4cbeb9cd18604fd16d1fa4c4350d8ab0
sha1:             eaa4b62ef92e9413477728325be004a5a43d4c83
ssdeep:           6144:NZ3RRJKEj8Emqh9ijN9MMd30zW73KQgpc837NBH:LhRzwEm7jEjz+/g2o7fH



Ligh, M. H., Case, A., Levy, J., & Walters, A. (2014). Art of memory forensics: Detecting malware and threats in Windows, Linux, and Mac memory
Ligh, M. H. (2011). Malware analyst’s cookbook and DVD: Tools and techniques for fighting malicious code.
Russinovich, M. E., Solomon, D. A., & Ionescu, A. (2012). Windows internals: Part 1
Russinovich, M. E., Solomon, D. A., & Ionescu, A. (2012). Windows internals: Part 2
Blunden, B. (2009). The rootkit arsenal: Escape and evasion in the dark corners of the system.
Zeltser, Lenny (2013) SANS FOR610: Reverse-Engineering Malware: Malware Analysis Tools and Techniques

Tagged , , , , , , ,

Memory Forensics with Volatility on REMnux v5 – Part 1

As threats and technology continue to evolve and malware becomes more sophisticated, the acquisition of volatility data and its forensic analysis is a key step during incident response and digital forensics. This article is about acquiring RAM from a disposable virtual machine before and after malware infection. This data will then be analyzed using the powerful Volatility Framework. The steps described here go hand in hand with the steps described on previous blog posts here and here about dynamic malware analysis.

We will use the methodology stated in previous post. We will start the virtual machine in a known clean state by restoring it from a snapshot or starting a golden copy. Then we will suspend/pause the machine in order to create a checkpoint state file. This operation will create a VMSS file inside the directory where the virtual machine is stored. Then we will use a tool provided by VMware named Vmss2core to convert this VMSS file into a WinDbg file (memory.dmp).  From VMware website: Vmss2core is a tool to convert VMware checkpoint state files into formats that third party debugger tools understand. Last version is available here. It can handle both suspend (.vmss) and snapshot (.vmsn) checkpoint state files as well as both monolithic and non-monolithic (separate .vmem file) encapsulation of checkpoint state data. This tools will allow us to convert the VMware memory file into a format that is readable by the Volatility Framework.

Next, we restore the virtual machine to back where it was and we infect it with malware. After that, we suspend the machine again and repeat the previous steps. This allow us to have two memory dumps that we can compare against each other in order to facilitate the finding of malicious code.

memory-analysis-2To perform the analysis and the memory forensics we will use the powerful Volatility Framework. The Volatility Framework born based on the research that was done by AAron Walters and Nick Petroni on Volatools and FATkit. The first release of the Volatility Framework was released in 2007. In 2008 the volatility team won the DFRWS and added the features used in the challenge to Volatility 1.3.  Seven years have passed and this framework has gained a lot of popularity and attention from the security community. The outcome has been a very powerful, modular and feature rich framework that combines a number of tools to perform memory forensics. The framework is written in Python and allows plugins to be easily added in order to add features. Nowadays it is on version 2.4, it supports a variety of operating systems and is being actively maintained.

Below the  steps needed to acquire the RAM data for a VMware virtual machine:

  • Restore the VMware snapshot to a known clean state.
  • Pause the Virtual Machine
  • Execute vmss2core_win.exe
  • Rename the memory.dmp file to memory-before.dmp
  • Resume the virtual machine
  • Execute the malware
  • Pause the virtual machine
  • Execute vmss2core_win.exe
  • Rename the memory.dmp file to memory-after.dmp

The following picture ilustrates the usage of Vmss2core_win.exe.


After performing this steps we can proceed to the analysis. First we move the memory dumps to REMnux. Then we start the Volatility Framework which comes pre-installed. We start our analysis by listing the process as a tree using the “pstree” module on both the clean and infected memory image. With this we can benchmark the infected machine and easily spot difference on infections performed by commodity malware.  In this case we can easily spot that on the infected machine there a process named explorer.exe (PID 1872) that references a parent process (PPID 1380) that is not listed. In addition we can observe the processes vssadmin.exe (PID 1168) and iexplorer.exe (PID 1224) which were spawned by explorer.exe.  Vsadmin.exe can manage volume shadow copies on the system. This strongly suggests that we are in presence of something suspicious.



Next step is to do a deep dive. During the previous dynamic malware analysis articles series were we analyzed the same piece of malware we were able to extract indicators of compromise (IOC). These IOC’s were extracted  from our analysis performed at the network level and system level. We will use this information for our own advantage in order to reduce the effort needed to find Evil. We knew that after the infection the malware will attempt to contact the C&C using a HTTP POST request to the URL topic.php which was hosted in Russia.

Let’s use this pieces of information to search and identify the malicious code. To perform this we will look for ASCII and UNICODE strings that match those artifacts using src_strings utility that is part of The Sleuth Kit from Brian Carrier and is installed on REMnux.


The  parameter “-t d” will tell the tool to print the location of the string in decimal. We save this findings in a text file. The results are  then used by Volatility. Next, we invoke Volatility and use the “strings” plugin that can map physical offsets to virtual addresses – this only works on raw memory images and not on crash dumps – . It works by traversing all the active processes  and is able to determine which ones accessed the specified strings.  In case of a match we will have a good hint on where the malicious code might reside. In this case the plugin is able to match the strings with the process ID 1872 on two different virtual addresses.  This corroborates the fact that on the previous step we saw this process without a parent process which was rather suspicions . Another clue that we might be in good direction.


This can be easily confirmed by listing the process ID 1872 using the “pslist” module.   Given this fact we proceed with the extract of this process from memory to a file using the “procmemdump” plugin. Volatility Framework is so powerful that it can parse PE headers in memory and carve them out. With this plugin we can dump the process executable using its PID.  After extraction we can verify that the file commands correctly identifies the file as a PE32 executable. Then we can verify that the string we found previous is indeed part of this process.


Well, looks like the string “topic.php” is not in the data we just extracted. However, as we could see in the previous analysis steps we determined that the actions performed by the malicious code were in the context of this process. Furthermore, during the basic static analysis performed (see previous post) on the malicious executable we saw that it references very few libraries but two of them were noteworthy. The LoadLibrary and GetProcAddress.  This suggest the malicious executable was either packed or encrypted. In addition those libraries suggest that  malicious code was injected into a process.  There are several techniques used by threat actors to inject malicious code into benign processes. I will expand on this techniques on a different blog post. As conclusion we might be looking at malicious code that was injected in the process explorer.exe (PID 1832) and is somehow concealed. This means we will need to look deeper into the obscure and fascinating world of memory forensics. Part two will follow!


Malware sample used in this exercise:

remnux@remnux:~/Desktop$ pehash torrentlocker.exe
file:             torrentlocker.exe
md5:              4cbeb9cd18604fd16d1fa4c4350d8ab0
sha1:             eaa4b62ef92e9413477728325be004a5a43d4c83
ssdeep:           6144:NZ3RRJKEj8Emqh9ijN9MMd30zW73KQgpc837NBH:LhRzwEm7jEjz+/g2o7fH


Ligh, M. H. (2011). Malware analyst’s cookbook and DVD: Tools and techniques for fighting malicious code.
Zeltser, Lenny (2013) SANS FOR610: Reverse-Engineering Malware: Malware Analysis Tools and Techniques

Tagged , , , ,