03 Jan 2026
These labs build on the basic Assembly exercises from Chapter 6 and demonstrate how to identify C constructs such as loops, conditionals, switch statements, etc.
This is a small sample with very basic functionality.
This question was deceptively simple and caused me to overthink it a bit, but the construct being referred to is a simple conditional. The result from InternetGetConnectedState is returned in EAX. That result is moved into var_4 and compared against 0. If the result is 0 (not connected), execution jumps to 0x40102b:
This one was a bit tricker. Quickly looking over the function itself does not reveal much:
Checking cross-references to see where this function is called makes it a little more obvious:

This is just the printf function! Apparently IDA does not always recognize these calls automatically.
This is just a simple program that checks whether the host has an active internet connection and prints the results to the console.
This sample builds on the first and expands the functionality slightly.
This is the same function from the previous sample used to determine whether the host is connected to the internet.
As with the previous sample, this is a call to printf that IDA did not automatically identify:
First, this function connects to a URL:
Then the contents of the file cc.htm are read:
And finally, the data that has been read is checked that it begins with the <!-- string. It appears that the command being read is hidden within an HTML comment:
The code construct used here is the character array (string) read from cc.htm.
The first indicator is the User Agent specified in the connection request, which is unusual:
The second indicator is the www.practicalmalwareanalysis.com/cc.htm URL that commands are read from.
This malware checks for an internet connection and if successful reads a command from an HTML comment hosted on a malicious website. This sample does not perform any functions with the command, but simply checks that a valid command is present and prints it to the console:
Again, this sample builds on the previous one and adds a switch statement for processing the command received.
After a command is successfully received from the malicious website, a call to a new function at 0x401130 has been added:
Before being called, the parsed command and an argv value that IDA has named lpExistingFileName are pushed to the stack:

Note that if this sample were run with no flags, argv would just be the name of the current program.
This function uses the command from the previous function to select a case from a switch statement:
There are 5 cases which can be chosen. The first case creates the directory C:\Temp:
The second case creates a copy of the current program at C:\Temp\cc.exe:
The third case deletes the C:\Temp\cc.exe copy:
The fourth case creates a registry key that will run the new malware copy at C:\Temp\cc.exe on startup. This key has the value name Malware 😂:
The fifth case simply sleeps for 100 seconds:
Host-based indicators would be the presence of cc.exe and the Malware registry key.
The purpose of this malware is to retrieve a command from a malicious webpage which tells the malware to copy itself to a new directory, delete the copied version, create a registry key that will run the new copy at startup, or sleep for 100 seconds.
The final form of this malware sample.
This sample adds a backward jump after the call to Sleep:
The code construct that has been added is a for loop. First, the counter is initialized to 0, then it is incremented by 1 for each iteration, and the loop is broken after 0x5a0, or 1,440 iterations:

Following the jump arrows at the left it can be seen where the counter initialization is jumped to after a successful internet connection test [1]. After initialization, the counter increment is jumped over for the first iteration [2]. After the rest of the function is completed, a jump is taken back to the counter increment and test [3]:
In this sample, the value of the loop counter is pushed to the stack before making the request:
The counter value is then appended to the User Agent string:
In this sample, the value passed to the Sleep function has been changed to 0xea60 milliseconds, or 60 seconds. If internet connectivity is maintained, 1,440 iterations means the program will run for roughly 24 hours:
Although I was already familiar with the idea of recognizing high-level programming constructs in assembly, these labs went into much more detail (especially breaking down the for loop in the fourth sample). This chapter was good practice for me and would be an excellent introduction to assembly and calling conventions for someone new.