Книга: Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software
Назад: Networking APIs
Дальше: Kernel vs. User Mode

and the functions covered throughout this chapter are all imported from the Windows DLLs. Throughout the balance of this chapter, we will continue to cover functions from specific DLLs and describe how malware uses them.

By using third-party DLLs

  • Malware can also use third-party DLLs to interact with other programs. When you see malware that imports functions from a third-party DLL, you can infer that it is interacting with that program to accomplish its goals. For example, it might use the Mozilla Firefox DLL to connect back to a server, rather than connecting directly through the Windows API. Malware might also be distributed with a customized DLL to use functionality from a library not already installed on the victim’s machine; for example, to use encryption functionality that is distributed as a DLL.

shows how CreateProcess could be used to create a simple remote shell. Prior to this snippet, code would have opened a socket to a remote location. The handle to the socket is stored on the stack and entered into the STARTUPINFO structure. Then CreateProcess is called, and all input and output for the process is routed through the socket.

). To discover which program will be run, we would need to find the string stored at dword_403098 by navigating to that address in IDA Pro.

Malware will often create a new process by storing one program inside another in the resource section. In , we discuss how the resource section of the PE file can store any file. Malware will sometimes store another executable in the resource section. When the program runs, it will extract the additional executable from the PE header, write it to disk, and then call CreateProcess to run the program. This is also done with DLLs and other executable code. When this happens, you must open the program in the Resource Hacker utility (discussed in ) and save the embedded executable file to disk in order to analyze it.

shows an example of accessing a local variable and pushing it on the stack.

, the code at accesses a local variable (esp+58h) and stores it in EDX, and then pushes EDX onto the stack. Now, if another thread were to run some code in between these two instructions, and that code modified EDX, the value of EDX would be wrong, and the code would not execute properly. When thread-context switching is used, if another thread runs in between these two instructions, the value of EDX is stored in the thread context. When the thread starts again and executes the push instruction, the thread context is restored, and EDX stores the proper value again. In this way, no thread can interfere with the registers or flags from another thread.

shows how to recognize the second technique by identifying two CreateThread calls near each other. (Only the system calls for ThreadFunction1 and ThreadFunction2 are shown.) This code calls CreateThread twice. The arguments are lpStartAddress values, which tell us where to look for the code that will run when these threads start.

, we have labeled the start function ThreadFunction1 for the first call to CreateThread and ThreadFunction2 for the second call . To determine the purpose of these two threads, we first navigate to ThreadFunction1. As shown in , the first thread function executes a loop in which it calls ReadFile to read from a pipe, and then it forwards that data out to a socket with the send function.

, the second thread function executes a loop that calls recv to read any data sent over the network, and then forwards that data to a pipe with the WriteFile function, so that it can be read by the application.

.

uses the hard-coded name HGL345 for the mutex. It first checks to see if there is a mutex named HGL345 using the OpenMutex call at . If the return value is NULL at , it jumps (at ) over the exit call and continues to execute. If the return value is not NULL, it calls exit at , and the process will exit. If the code continues to execute, the mutex is created at to ensure that additional instances of the program will exit when they reach this code.

.)

The information about services on a local system is stored in the registry. Each service has a subkey under HKLM\SYSTEM\CurrentControlSet\Services. For example, shows the registry entries for HKLM\SYSTEM\CurrentControlSet\Services\VMware NAT Service.

in a more readable way. shows the SC program in action.

shows the query configuration information command. This information is identical to what was stored in the registry for the VMware NAT service, but it is easier to read because the numeric values have meaningful labels such as WIN32_OWN_PROCESS . The SC program has many different commands, and running SC without any parameters will result in a list of the possible commands. (For more about malware that runs as a service, see .)

shows how some code gets access to an IWebBrowser2 object.

shows the call. The reference to the COM object is stored on the stack, and then moved into EAX. Then the first value in the structure points to a table of function pointers. At an offset of 0x2C in the table is the Navigate function that is called.

shows disassembly for the first few lines of a function that has exception handling.

–, , and ).

Назад: Networking APIs
Дальше: Kernel vs. User Mode

sss
sss

© RuTLib.com 2015-2018