Breakpoints

As discussed in Chapter 8, there are several different types of breakpoints, and OllyDbg supports all of those types. By default, it uses software breakpoints, but you can also use hardware breakpoints. Additionally, you can set conditional breakpoints, as well as set breakpoints on memory.

You can add or remove a breakpoint by selecting the instruction in the disassembler window and pressing F2. You can view the active breakpoints in a program by selecting ViewBreakpoints or clicking the B icon in the toolbar.

After you close or terminate a debugged program, OllyDbg will typically save the breakpoint locations you set, which will enable you to debug the program again with the same breakpoints (so you don’t need to set the breakpoints again). Table 9-2 shows a complete listing of OllyDbg’s breakpoints.

Table 9-2. OllyDbg Breakpoint Options

Function

Right-click menu selection

Hotkey

Software breakpoint

Breakpoint ▸ Toggle

F2

Conditional breakpoint

Breakpoint ▸ Conditional

SHIFT-F2

Hardware breakpoint

Breakpoint ▸ Hardware, on Execution

 

Memory breakpoint on access (read, write, or execute)

Breakpoint ▸ Memory, on Access

F2 (select memory)

Memory breakpoint on write

Breakpoint ▸ Memory, on Write

 

Software Breakpoints

Software breakpoints are particularly useful when debugging a string decoder function. Recall from Chapter 1 that strings can be a useful way to gain insight into a program’s functionality, which is why malware authors often try to obfuscate strings. When malware authors do this, they often use a string decoder, which is called before each string is used. Example 9-2 shows an example with calls to String_Decoder after obfuscated data is pushed on the stack.

Example 9-2. A string decoding breakpoint

push offset "4NNpTNHLKIXoPm7iBhUAjvRKNaUVBlr"
call String_Decoder
...
push offset "ugKLdNlLT6emldCeZi72mUjieuBqdfZ"
call String_Decoder
...

The obfuscated data is often decoded into a useful string on the stack, so the only way to see it is to view the stack once the string decoder is complete. Therefore, the best place to set a breakpoint to view all of the strings is at the end of the string decoder routine. In this way, each time you choose Play in OllyDbg, the program will continue executing and will break when a string is decoded for use. This method will identify only the strings the program uses as it uses them. Later in this chapter, we will discuss how to modify instructions to decode all of the strings at once.

Conditional Breakpoints

As you learned in the previous chapter, conditional breakpoints are software breakpoints that will break only if a certain condition is true. OllyDbg allows you to set conditional breakpoints using expressions; each time the software breakpoint is hit, the expression is evaluated. If the expression result is nonzero, execution pauses.

Warning

Be careful when using conditional breakpoints. Setting one may cause your program to run much more slowly, and if you are incorrect about your condition, the program may never stop running.

Conditional software breakpoints can be particularly useful when you want to save time when trying to pause execution once a certain parameter is passed to a frequently called API function, as demonstrated in the following example.

You can use conditional breakpoints to detect memory allocations above a certain size. Consider Poison Ivy, a popular backdoor, which receives commands through the Internet from a command-and-control server operated by an attacker. The commands are implemented in shellcode, and Poison Ivy allocates memory to house the shellcode it receives. However, most of the memory allocations performed in Poison Ivy are small and uninteresting, except when the command-and-control server sends a large quantity of shellcode to be executed.

The best way to catch the Poison Ivy allocation for that shellcode is to set a conditional breakpoint at the VirtualAlloc function in Kernel32.dll. This is the API function that Poison Ivy uses to dynamically allocate memory; therefore, if you set a conditional breakpoint when the allocation size is greater than 100 bytes, the program will not pause when the smaller (and more frequent) memory allocations occur.

To set our trap, we can begin by putting a standard breakpoint at the start of the VirtualAlloc function to run until the breakpoint is hit. Figure 9-7 shows the stack window when a breakpoint is hit at the start of VirtualAlloc.

Stack window at the start of VirtualAlloc

Figure 9-7. Stack window at the start of VirtualAlloc

The figure shows the top five items on the stack. The return address is first, followed by the four parameters (Address, Size, AllocationType, and Protect) for VirtualAlloc. The parameters are labeled next to their values and location in the stack. In this example, 0x29 bytes are to be allocated. Since the top of the stack is pointed to by the ESP register in order to access the Size field, we must reference it in memory as [ESP+8].

Figure 9-8 shows the disassembler window when a breakpoint is hit at the start of VirtualAlloc. We set a conditional breakpoint when [ESP+8]>100, in order to catch Poison Ivy when it is about to receive a large amount of shellcode. To set this conditional software breakpoint, follow these steps:

  1. Right-click in the disassembler window on the first instruction of the function, and select Breakpoint ▶ Conditional. This brings up a dialog asking for the conditional expression.

  2. Set the expression and click OK. In this example, use [ESP+8]>100.

  3. Click Play and wait for the code to break.

Setting a conditional breakpoint in the disassembler window

Figure 9-8. Setting a conditional breakpoint in the disassembler window

Hardware Breakpoints

OllyDbg provides functionality for setting hardware breakpoints through the use of dedicated hardware registers, as described in Chapter 8.

Hardware breakpoints are powerful because they don’t alter your code, stack, or any target resource. They also don’t slow down execution speed. As we noted in the previous chapter, the problem with hardware breakpoints is that you can set only four at a time.

To set hardware breakpoints on an instruction, right-click that instruction and select Breakpoint ▶ Hardware, on Execution.

You can tell OllyDbg to use hardware breakpoints instead of software breakpoints by default by using the Debugging Options menu. You might do this in order to protect against certain anti-debugging techniques, such as software breakpoint scanning, as we’ll discuss in Chapter 16.

Memory Breakpoints

OllyDbg supports memory breakpoints, allowing you to set a breakpoint on a chunk of memory in order to have the code break on access to that memory. OllyDbg supports the use of software and hardware memory breakpoints, as well as the ability to specify whether you want it to break on read, write, execute, or any access.

To set a basic memory breakpoint, select a portion of memory in the memory dump window or a section in the memory map, right-click it, and select Breakpoint ▶ Memory, on Access. You can set only one memory breakpoint at a time. The previously set memory breakpoint is removed if you set a new one.

OllyDbg implements software memory breakpoints by changing the attributes of memory blocks containing your selection. However, this technique is not always reliable and can bring with it considerable overhead. Therefore, you should use memory breakpoints sparingly.

Memory breakpoints are particularly useful during malware analysis when you want to find out when a loaded DLL is used: you can use a memory breakpoint to pause execution as soon as code in the DLL is executed. To do this, follow these steps:

  1. Bring up the Memory Map window and right-click the DLL’s .text section (the section that contains the program’s executable code).

  2. Select Set Memory Breakpoint on Access.

  3. Press F9 or click the play button to resume execution.

The program should break when execution ends up in the DLL’s .text section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.67.235