Passerby A · 2015/06/29 11:04

This tutorial series focuses on Modern Windows Exploit Development.

Familiarity with x86 assembly language is required, and you should be able to reproduce some of the experiments I’ve done since it’s easy to get hands-on with the tutorials. Later in the series, we will experiment with attacks on Internet Explorer 10 and 11. My main goal is not only to show you how to attack Internet Explorer, but also to show you the research that you need to do before you can launch such a complex attack to achieve your desired goal. Part of this tutorial series will go into the details of reverse engineering Internet Explorer to see how objects are laid out in memory and how to leverage what we already know.

I recommend that you create two virtual machines on 64-bit Windows 7 SP1: one for Internet Explorer 10-related experiments and one for Internet Explorer 11-related experiments. I hope you enjoyed this series of tutorials!

Source: http://expdev-kiuhnm.rhcloud.com/2015/05/17/windbg/

This article describes some of winDBG’s most important commands and their most important options. Of course, we’ll learn about other commands and options when needed in the next article.

version

To avoid problems:

Use the 32-bit version of WinDbg to debug 32-bit executable programs. Use the 64-bit version of WinDbg to debug 64-bit executables.

symbol

Open an instance of WinDbg. If you are debugging a process using WinDbg, close WinDbg and restart it. 
 is in File→Symbol File Path

Input: the SRV * C: \ windbgsymbols * http://msdl.microsoft.com/download/symbols

Save the Workspace (File→Save Workspace).

The asterisk above is the definition. The directory specified above is the local symbol cache directory. Paths /urls are placed after the second asterisk (if there are more paths/urls, use ‘; ‘Split). Use an asterisk to specify the position of the symbol.

Add symbols while debugging

To append the search path of the symbol when debugging, use the.sympath+ c:\symbolpath command

(The command used without ‘+’ replaces the default search path)

Reload the symbol table :.reload

Check the symbol

If you need to know which symbols the module loaded, use the command: x *!

The X command supports the use of wildcards and can be used when searching for symbols in one or more modules. For example, we could search for all symbols in kernel32 that begin with the word virtual:

#! bash 0:000> x kernel32! virtual* 757d4b5f kernel32! VirtualQueryExStub (<no parameter info>) 7576d950 kernel32! VirtualAllocExStub (<no parameter info>) 757f66f1 kernel32! VirtualAllocExNuma (<no parameter info>) 757d4b4f kernel32! VirtualProtectExStub (<no parameter info>) 757542ff kernel32! VirtualProtectStub (<no parameter info>) 7576d975 kernel32! VirtualFreeEx (<no parameter info>) 7575184b kernel32! VirtualFree (<no parameter info>) 75751833 kernel32! VirtualAlloc (<no parameter info>) 757543ef kernel32! VirtualQuery (<no parameter info>) 757510c8 kernel32! VirtualProtect (<no parameter info>) 757ff14d kernel32! VirtualProtectEx (<no parameter info>) 7575183e kernel32! VirtualFreeStub (<no parameter info>) 75751826 kernel32! VirtualAllocStub (<no parameter info>) 7576d968 kernel32! VirtualFreeExStub (<no parameter info>) 757543fa kernel32! VirtualQueryStub (<no parameter info>) 7576eee1 kernel32! VirtualUnlock (<no parameter info>) 7576ebdb kernel32! VirtualLock (<no parameter info>) 7576d95d kernel32! VirtualAllocEx (<no parameter info>) 757d4b3f kernel32! VirtualAllocExNumaStub (<no parameter info>) 757ff158 kernel32! VirtualQueryEx (<no parameter info>)Copy the code

Use wildcards in module sections:

#! bash 0:000> x *! messagebox* 7539fbd1 USER32! MessageBoxIndirectA (<no parameter info>) 7539fcfa USER32! MessageBoxExW (<no parameter info>) 7539f7af USER32! MessageBoxWorker (<no parameter info>) 7539fcd6 USER32! MessageBoxExA (<no parameter info>) 7539fc9d USER32! MessageBoxIndirectW (<no parameter info>) 7539fd1e USER32! MessageBoxA (<no parameter info>) 7539fd3f USER32! MessageBoxW (<no parameter info>) 7539fb28 USER32! MessageBoxTimeoutA (<no parameter info>) 7539facd USER32! MessageBoxTimeoutW (<no parameter info>)Copy the code

If you want to change the policy temporarily and load all module symbols into the WinDbg debugger at once, you can use ld*

This could take a while. You can stop debugging by running Debug→Break.

help

Just type.hh or press F1 to open the help window. Use the following command to get help information about the specified command:

.hh <command>
Copy the code

for a specific command for which you want help information, or press F1 and select Index to search for a command to get help information.

Debug mode

Local debugging

You can debug a new process or a running process:

Run the new process through File→Open Executable for debugging

Attach to a running Process by File→Attach to a Process

Remote debugging

Use at least two of the following options to debug the program remotely

1 If you are already debugging A program locally on machine A, use the following command (select the port you want):

.server tcp:port=1234
Copy the code

Start the server (WinDbg). Go to File→Connect to Remote Sessions and enter:

tcp:Port=1234,Server=<IP of Machine A>
Copy the code

To specify the port and IP.

2 On machine A, run the following command to run DBGSRV:

dbgsrv.exe -t tcp:port=1234
Copy the code

That is, the server can be started on machine A.

Run Windbg on machine B, then File→Connect to Remote Stub, enter

tcp:Port=1234,Server=<IP of Machine A>
Copy the code

The appropriate parameters need to be set here.

You will see that File→Open Executable is no longer available, but you can Attach to the process by File→Attach to a process. You can see A list of processes on machine A.

To stop the server on machine A, use Task Manager to kill dbgsrv.exe.

The module

When you load an executable or attach it to a process,WinDbg lists the loaded modules. If you want to list the module again, then you can enter: LMF list the specified module (ntDLl.dll), can use: LMF m NTDLL to get the module (ntDLl.dll) image header information:! dh ntdll

With ‘! The ‘command is an extension command that displays detailed information about the specified module, and so on. Export an external command from an external DLL and call it internally from WinDbg. Users can create their own extensions to extend the functionality of WinDbg.

Of course, you can also use the starting address of the module:

#! bash 0:000> lmf m ntdll start end module name 77790000 77910000 ntdll ntdll.dll 0:000> ! dh 77790000Copy the code

expression

WinDbg supports expressions, which means that when you need a value, you can enter it directly or an expression equivalent to it. For example, if EIP is 77C6CB70, then BP77C6CB71 and BP EIP+1 are equivalent.

You can also use the notation: u NTDLL! CsrSetPriorityClass+0x41 and register :dd ebp+4 Numbers are represented by base 16 by default, prefix is added to specify the base format used:

#! Bash 0x123: Base 16 (Hexadecimal)
 0n123: Base 10 (Decimal)
 0t123: Base 8 (octal)
 0y111: Base 2 (binary)Copy the code

Use the. Format command to display multiple formats of a value

#! bash 0:000> .formats 123 Evaluate expression: Hex: 00000000`00000123 Decimal: 291 Octal: 0000000000000000000443 Binary: 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00100011 Chars: ....... # Time: Thu Jan 01 01:04:51 1970 Float: low 4.07778E-043 high 0 Double: 1.43773E-321Copy the code

Use ‘? ‘to evaluate an expression, for example 😕 eax+4

Registers and pseudo registers

In WinDbg, there are many pseudo registers (with certain values) supported. The prefix ‘$’ is used to indicate that it is a pseudo register. When using registers or pseudo registers, [email protected], [email protected] instead of a symbol.

Here are some examples of pseudo registers:

$teb or @$teb (address of teB)

$PEb or @$peb (address of PEB)

$thread or @$thread (current thread)

abnormal

You can interrupt a specific exception with the sxe command. For example, to interrupt a module that has been loaded, type:

sxe ld <module name 1>,... ,<module name N>Copy the code

For example,

sxe ld user32
Copy the code

View the list of exception types: SX Ignores an exception by running the sxi command: sXI LD This command invalidates the first command entered.

Exceptions to single-chance and second-chance will interrupt Windbg. They are not different types of exceptions. When execution reaches an exception, WinDbg stops execution and prompts that the location is a single-chance exception. Single-chance means that the exception event has not yet been sent to the program being debugged. When we resume execution,WinDbg sends the exception event to the debugged program. If the debugger does not handle the exception,WinDbg stops execution again with a message indicating a second-chance exception.

When we test EMET5.2, we need to ignore single-chance’s Single step exceptions. Run the following command: SXD SSE

The breakpoint

Software breakpoints:

When a breakpoint is set on an instruction,WinDbg stores the first byte of the instruction in memory and overwrites it with 0xCC (opcode “int 3”).

When the “int 3” instruction is executed, the breakpoint is triggered, execution is stopped, and WinDbg resets the instruction by resetting its first byte.

Enter the following command to set a breakpoint on the instruction at address 0x4110A0:

bp 4110a0
Copy the code

Enable breakpoint at 0x4110A0 on the third run:

bp 4110a0 3
Copy the code

To resume execution (and stop at the breakpoint triggered for the first time) enter the following: g

This is short for “go”.
 Run until you reach an address (with code), type :g

A software breakpoint (such as’ bp ‘) will be set in WinDbg at the specified location, but the breakpoint will be removed when triggered. The main reason is that ‘G’ is used to set a one-time software breakpoint.

Hardware breakpoint

Hardware breakpoints are set with specific CPU registers, which are more generic than software breakpoints. In fact, it can interrupt execution or memory access. Hardware breakpoints do not modify arbitrary code and even come with self modifying code. Unfortunately, a maximum of four hardware breakpoints can be set.

The simplest command format is as follows:

Ba <mode> <size> <address> <passes (default=1)> <mode> can be 'e' for performing 'r' for reading memory and 'w' for writing memoryCopy the code


is the size of the monitoring access (which is always 1 when

is’ e ‘) to indicate the location, expressed in bytes. 


is the location where the breakpoint is set and is the number of passes required when the breakpoint is activated (see ‘bp’ usage example), which acts as a counter.


Note: It is not possible for a process to use a hardware breakpoint before running it. Because by modifying the CPU registers (DR0, DR1, etc…) Hardware breakpoints can be set so that registers are reset when the start process and its threads are created.

Handle the breakpoint

List the breakpoint type: BL

‘bl’ indicates breakpoint list.
 For example:

0:000> bl 0 e 77c6cb70 0002 (0002) 0:**** ntdll! CsrSetPriorityClass+0x40Copy the code

The locations of the regions, from left to right, are shown as follows:

0: indicates the ID of the breakpoint

E: Indicates the breakpoint status. The value can be enabled or disabled.

77C6CB70: indicates the memory address

0002 (0002) : the rest of the transfer number before activation (counter effect), use all transfer number to wait for the activation (when a breakpoint is created, will be the value specified) 0: | * * * * : the associated processes and threads. The asterisk indicates that the breakpoint is not Thread-specific.

ntdll! CsrSetPriorityClass+0x40: Set breakpoint location (module, function and offset)

Disable a breakpoint

bd <breakpoint id>
Copy the code

Remove breakpoints

bc <breakpoint ID>
Copy the code

Delete all breakpoints

bc *
Copy the code

Breakpoint commands

Each time a breakpoint is triggered, a command is automatically executed. You can run the following command:

bp 40a410 ".echo \"Here are the registers:\n\"; r"
Copy the code

Another example: the custom command looks like this:

bp jscript9+c2c47 ".printf \"new Array Data: addr = 0x%p\\n\",eax; g"Copy the code

Perform step by step

There are at least three types of step-by-step implementation:

Step/trace (command :t) This command interrupts the execution of each command. If a call directive or an int directive is executed, the command is broken on the first instruction or int handler that calls the function, respectively. Step (command: p) This command will interrupt every instruction (no calls or ints, etc.) after execution. If you happen to be executing a call or int, it will interrupt the step after execution of a call or int (command: Gu this command (go up) allows WinDbg to resume the execution of the program and to interrupt after the next ret command. This command is often used in the exit function.

There are two other commands for the exit function:

Tt (trace to Next return): This is equivalent to repeating the ‘t’ command and stopping execution on the first ret instruction encountered during execution. Pt (step to Next return): This is equivalent to repeating the ‘p’ command and stopping execution on the first RET instruction encountered during execution.

Note: using tt will execute into the function, if you want to reach ret of the current function, use pt instead. The difference between the pt command and the gu command is that the pt command will interrupt the RET command, and the GU command will interrupt the next command after the RET command.

Here are the different forms of the commands containing ‘p’ and ‘t’ :

Pa /ta <address>: step/trace the address. PC/TC: Step /trace to the next call/int instruction. Pt/TT: step/trace the next ret (Discussed above at Point 3) instruction. PCT/TCT: Step /trace to the next call/int or RET instruction. Ph/TH: step/trace instructions to the next branch.Copy the code

Check the memory

You can use ‘d’ or one of its variables to display the contents of memory,

db: display bytes
dw: display words (2 bytes)
dd: display dwords (4 bytes)
dq: display qwords (8 bytes)
dyb: display bits
da: display null-terminated ASCII strings
du: display null-terminated Unicode strings
Copy the code

Type.hh d to view the other variables. The ‘d’ command presents the data in the same format as most D * commands (or db if it is not single data).

The (simplified) format of these commands is: d* [range]

Here, use an asterisk to describe all of the changes we have listed above, and the box should indicate the selected range. If the range is not selected, the memory portion of the data will be displayed after the d* command is used to display some of the data.

Ranges can be specified in a number of ways:

  1. <start address> <end address>College paradigm,db 77cac000 77cac0ff
  2. <start address> L<number of elements>College paradigm,dd 77cac000 L10View 10 dwords (starting at 77cac000 address).
Note: Since the range is larger than 256 MB, we must use L? Instead of L, specify the number of rows.
  3. <start address>
  4. Using WinDbg, you can view 128 bytes of content when you just specify the starting address.

Edit memory

To edit memory, use:

e[d|w|b] <address> [<new value 1> ... <new value N>]
Copy the code

| | w b [d] is related options, it specifies the element type of the editor (d = dword, w = word, b = byte). If the new values are omitted, you can enter them interactively in WinDbg.

Here’s the example: Ed eip cc cc

Override the first two Dwords on the address (within the EIP) with the value 0xCC.

Search the memory

Use the ‘s’ command to search memory. Its format is:

s [-d|-w|-b|-a|-u] <start address> L? <number of elements> <search values>Copy the code

D, W, B, a, and u stand for DWord, Word, Byte, ASCII, and Unicode respectively.


is a sequence value (for searching)

Such as:

s -d eip L? 1000 cc ccCopy the code

Search for two consecutive dwords 0xcc 0xcc in memory. [EIP, eIP + 1000 x 4-1].

Pointer to the

Dereference a pointer with the following command:

dd poi(ebp+4)
Copy the code

With this command, POI (ebp+4) evaluates the address EBP +4, and the result is of type Dword or qword(in 64-bit mode).

Commands that are used for more than one aspect

To view the register information, enter r

To view specific register information, such as eAX and ADx, type: r eax, edx

Run the following command to print the first three EIP instructions: u EIP L3

‘U’ is short for unassemble and the ‘L’ lets you specify the number of lines you want to view the message. To list the call stack, use k

Dump structure

Here are some commands to view structure information:

You are advised to set up the following workspace environment

Save Workspace after creating window (File→Save Workspace)