March 10, 2014

On-the-fly Switching Between Debuggers

Sometimes it's useful to switch between debuggers without restarting the target application. An example for doing so is when you want to use another debugger's capability that the one doesn't have. Here is how to do by using the well-known EB FE trick.
  • Instruct the debugger to break-in, and memorize the two bytes at EIP.
  • Replace the two bytes at EIP with EB FE that is JMP EIP.
  • Detach the debugger leaving the application in an endless loop.
  • Attach the other debugger to the running process.
  • Locate the thread of the endless loop by switching between threads, and when found, restore the two bytes you memorized.
  • Carry-on with the debugging using the other debugger.
Note, the patched thread could interfere with watchdog thread if any, however I haven't experienced it yet.

March 5, 2014

Trace And Watch

This is how I recently performed dynamic integer analysis on a 32-bit binary application that reads DWORD values from the file.
  • The file format contains many fields of type DWORD. There was given a sample file. I made as many copies of the sample file as many DWORD fields it had. I crafted each sample to have 0x41414141 in a DWORD field. Only one DWORD field was changed per sample so all DWORD fields were covered by the change.
  • I wrote a PinTool, called TraceAndWatch, for this occassion that checks the value of the general registers before every instruction is executed. It shows memory state including disassembly of the instruction when a register value matches 0x41414141.
  • I executed the application using TraceAndWatch and let the application to parse the first sample containing 0x41414141. TraceAndWatch produced a log and I saw what instructions using 0x41414141.
  • In static disassembly code, I located the instructions using 0x41414141 and saw arithmetic and comparison operations with that value.
  • In some cases I realized I can enter to other code path by changing 0x41414141 in the sample to other value e.g. to signed value like 0x88888888. And re-run the test with TraceAndWatch specifying to trace and watch instructions using 0x88888888.
  • I executed this manual test on all the samples produced earlier.

The following weaknesses can be audited by this approach.

CWE-839: Numeric Range Comparison Without Minimum Check
CWE-195: Signed to Unsigned Conversion Error
CWE-682: Incorrect Calculation
CWE-190: Integer Overflow or Wraparound
CWE-680: Integer Overflow to Buffer Overflow
CWE-191: Integer Underflow (Wrap or Wraparound)

Final Notes

This is a generic, and quick way to locate comparison and arithmetic of integers.

TraceAndWatch doesn't track other than general registers so you can loose track of integers when value copied to, like, SSE register.

When arithmetic is performed on the value e.g. 0x41414141 is multiplied by 2, you need to set TraceAndWatch to look for 0x82828282 not to loose the tracking.

TraceAndWatch is available for download on my OneDrive space. If you use it you may contact me with your experience.
  This blog is written and maintained by Attila Suszter. Read in Feed Reader.