INT 3
breakpoints, the memory breakpoint provided by OllyDbg, hardware breakpoints, and run tracing with break conditions.Packed code and the unpacking stub are often unlike the code that debuggers ordinarily deal with. Packed code is often self-modifying, containing call
instructions that do not return, code that is not marked as code, and other oddities. These features can confuse the debuggers and cause breakpoints to fail.
Using an automated tool to find the OEP is the easiest strategy, but much like the automated unpacking approach, these tools do not always work. You may need to find the OEP manually.
jmp
instruction. In the case of a tail jump, IDA Pro encounters an error and colors the jump red.ADD BYTE PTR DS:[EAX],AL
corresponds to two 0x00 bytes, which is not a valid instruction, but OllyDbg is attempting to disassemble this instruction anyway.Example 18-4. Call to an imported function when the import table is not properly reconstructed
push eax call dword_401244 ... dword_401244: 0x7c4586c8
The listing shows a call
instruction with a target based on a DWORD
pointer. In IDA Pro, we navigate to the DWORD
and see that it has a value of 0x7c4586c8
, which is outside our loaded program. Next, we open OllyDbg and navigate to the address 0x7c4586c8 to see what is there. OllyDbg has labeled that address WriteFile
, and we can now label that import address as imp_WriteFile
, so that we know what the function does. You’ll need to go through these steps for each import you encounter. The cross-referencing feature of IDA Pro will then label all calls to the imported functions. Once you’ve labeled enough functions, you can effectively analyze the malware.
The main drawbacks to this method are that you may need to label a lot of functions, and you cannot search for calls to an import until you have labeled it. The other drawback to this approach is that you can’t actually run your unpacked program. This isn’t a showstopper, because you can use the unpacked program for static analysis, and you can still use the packed program for dynamic analysis.
Another strategy, which does allow you to run the unpacked program, is to manually rebuild the import table. If you can find the table of imported functions, then you can rebuild the original import table by hand. The PE file format is an open standard, and you can enter the imported functions one at time, or you could write a script to enter the information for you. The biggest drawback is that this approach can be very tedious and time-consuming.
Sometimes malware authors use more than one packer. This doubles the work for the analyst, but with persistence, it’s usually possible to unpack even double-packed malware. The strategy is simple: Undo the first layer of packing using any of the techniques we’ve just described, and then repeat to undo the second layer of packing. The strategies are the same, regardless of the number of packers used.