Breakpoints 101

So I thought I would do something about breakpoints.. something basic and build it up to something useful.

I use notepad for all the tests and the symbols path is:

0:002> .sympath

Symbol search path is: https://msdl.microsoft.com/download/symbols

The basic commands for breakpoints are ( see the help for more detailed info on each one of these )

bp

Set a breakpoint on an address

bl

List breakpoints

bd

Disable breakpoint(s)

bc

Clear breakpoints(s)

be

Enable breakpoint(s)

ba

Break on access to a specific memory address

Here are a few examples:

Let’s set a breakpoint on CreateFileW. First we find the address via the ‘x’ command and pass the function ( we could have used wildcards in the name like createfil* )

0:002> x kernel32!createfileW

7c810760 kernel32!CreateFileW = <no type information>

0:002> bp 7c810760

Now list our current breakpoints.. note the small blue ‘e’ - means its enabled.

0:002> bl

 0 e 7c810760 0001 (0001) 0:**** kernel32!CreateFileW

Now set another bp using the symbolic name

0:002> bp kernel32!createfileA

0:002> bl

 0 e 7c810760 0001 (0001) 0:**** kernel32!CreateFileW

 1 e 7c801a24 0001 (0001) 0:**** kernel32!CreateFileA

Disable all bp’s – see the ‘e’ has turned to ‘d’ – disabled.

0:002> bd *

0:002> bl

 0 d 7c810760 0001 (0001) 0:**** kernel32!CreateFileW

 1 d 7c801a24 0001 (0001) 0:**** kernel32!CreateFileA

Enable one or more – if you did a ‘be *’ it enables all – or you can do ‘be 0 1 3 5’ etc.. to enable bp’s 0,1,3 and 5

0:002> be 1

0:002> bl

 0 d 7c810760 0001 (0001) 0:**** kernel32!CreateFileW

 1 e 7c801a24 0001 (0001) 0:**** kernel32!CreateFileA

 

[ ~ Thread] bp[ID] [Options] [Address [Passes]] [ " CommandString " ]

The command tring is the interesting part here. Very useful as we will see later.

First let’s hit our breakpoint and poke around a bit.

Give the debugger a “go” via ‘g’

0:005> g

Breakpoint 0 hit

eax=0007d004 ebx=0007d004 ecx=00000003 edx=0007cd88 esi=00000000 edi=00000000

eip=7c810760 esp=0007cb14 ebp=0007cd54 iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202

kernel32!CreateFileW:

7c810760 8bff mov edi,edi

Show some of the stack..

0:000> kbL3

ChildEBP RetAddr Args to Child

0007cb10 77f67faf 0007d004 80000000 00000005 kernel32!CreateFileW

0007cd54 77f7a1aa 0007d004 80000000 00000005 SHLWAPI!CreateFileWrapW+0x73

0007cd8c 7ca05b66 0007d004 00000020 00000000 SHLWAPI!SHCreateStreamOnFileEx+0x48

Moving right along…..

The CreateFile function takes many parameters – but if we look at just the first one, it is a pointer to a string.

HANDLE CreateFile(

  LPCTSTR lpFileName,

  DWORD dwDesiredAccess,

  DWORD dwShareMode,

  LPSECURITY_ATTRIBUTES lpSecurityAttributes,

  DWORD dwCreationDisposition,

  DWORD dwFlagsAndAttributes,

  HANDLE hTemplateFile

);

The stack listing via ‘kb’ only shows the first 3 parameters … we can see the rest by looking at the data relative to the base pointer or EBP.

The output below via the ‘dd’ command shows us the memory in 4 byte chunks – or DWORDS. I have highlighted the 7 parameters passed to CreateFileW

The blue is the address – so the address 0007cd54 contains 0007cd8c .

0:000> dd ebp

0007cd54  0007cd8c 77f7a1aa 0007d004 80000000

0007cd64 00000005 00000000 00000003 00000000

0007cd74 00000000 0007d004 77f7a166 000ce218

0007cd84 80000000 00000005 0007cfcc 7ca05b66

0007cd94 0007d004 00000020 00000000 00000003

0007cda4 00000000 0007cdb8 000d4238 00000000

0007cdb4 763b6eb4 00000000 0007cf2c 000000f6

0007cdc4 7c90fb3d 0007cdbc 00001c37 0007ce28

This may make it easier to see ( via the ‘dds’ command ) – remember we are dumping it in 4 byte blocks – DWORDS

0:000> dds ebp

0007cd54 0007cd8c

0007cd58 77f7a1aa SHLWAPI!SHCreateStreamOnFileEx+0x48

0007cd5c 0007d004 --> 4 bytes. 00,07,d0,04 ( remember 8 bits is a byte )

0007cd60 80000000

0007cd64 00000005

0007cd68 00000000

0007cd6c 00000003

0007cd70 00000000

0007cd74 00000000

0007cd78 0007d004

0007cd7c 77f7a166 SHLWAPI!SHCreateStreamOnFileEx

0007cd80 000ce218

0007cd84 80000000

Now each address is clearly identified and shows what is there.

0007cd5c contains 0007d004

0007cd60 contains 80000000

And so on...

You may have noticed I am using the alias ‘ebp’ and the debugger understands that as the EBP register and dumps its value.when used in general commands:

Here we display the register itself:

0:000> r ebp

ebp=0007cd54

EBP+8 in this case , is the first parameter to CreateFile – which is a pointer to the string. Let’s see if that’s true – 0007d004 should be the start of some string.

We can initially poke at it via ‘dc” – which dumps double-word values (4 bytes) and ASCII characters.

0:000> dc 0007d004

0007d004 003a0043 0044005c 0063006f 006d0075 C.:.\.D.o.c.u.m.

0007d014 006e0065 00730074 00610020 0064006e e.n.t.s. .a.n.d.

0007d024 00530020 00740065 00690074 0067006e .S.e.t.t.i.n.g.

0007d034 005c0073 00740073 00760065 005c0065 s.\.s.t.e.v.e.\.

0007d044 00650044 006b0073 006f0074 005c0070 D.e.s.k.t.o.p.\.

0007d054 006f0042 006c0069 006f0073 00740066 B.o.i.l.s.o.f.t.

0007d064 004d0020 0056004f 00430020 006e006f .M.O.V. .C.o.n.

0007d074 00650076 00740072 00720065 006c002e v.e.r.t.e.r...l.

Cool – but it’s not so friendly... let’s use ‘du’ which will dump the Unicode characters up to the null terminator

0:000> du 0007d004

0007d004 "C:\Documents and Settings\steve\"

0007d044 "Desktop\Boilsoft MOV Converter.l"

0007d084 "nk"

Much nicer – we have a regular looking string – some .lnk file.

But let’s do it all in one step – we can dereference the pointer via the ‘poi’ operator

0:000> du poi(0007cd94)

0007d004 "C:\Documents and Settings\steve\"

0007d044 "Desktop\Boilsoft MOV Converter.l"

0007d084 "nk"

Better – but what if we don’t want to hardcode the pointer? Recall that 0007cd94 is simply EBP+8 which is really the first parameter.

0:000> du poi(ebp+8)

0007d004 "C:\Documents and Settings\steve\"

0007d044 "Desktop\Boilsoft MOV Converter.l"

0007d084 "nk"

Ahh much better… so let’s bring this back to our simple breakpoint :

0:000> bl

 0 e 7c810760 0001 (0001) 0:**** kernel32!CreateFileW

Let’s use that commandstring parameter I mentioned earlier – the interesting one…

A refresher from the help file shows the usage as follows:

[ ~ Thread] bp[ID] [Options] [Address [Passes]] [ " CommandString " ]

So.. we can do :

0:000> bp 7c810760 "du poi(ebp+8);g"

breakpoint 0 redefined

0:000> g

Which reads as “set a break point on address 7c810760 , and when you hit it – evaluate the command string and do what it says, which is to dump the data that ebp+8 points to as a Unicode string , and then , go.”

We give it a go – and then in notepad, click on file “save as”

0007ddd8 "C:\Documents and Settings\steve\"

0007de18 "Desktop\Shortcut to NOTES.doc.ln"

0007de58 "k"

000e1e80 "C:\Documents and Settings\steve\"

000e1ec0 "Desktop\ntoskrnl.pdb\"

000e1e80 "C:\Documents and Settings\steve\"

000e1ec0 "Desktop\ntoskrnl.pdb\"

000e1e80 "C:\Documents and Settings\steve\"

000e1ec0 "Desktop\"

000e1e80 "C:\Documents and Settings\steve\"

000e1ec0 "Desktop\"

000e1e80 "C:\Documents and Settings\steve\"

000e1ec0 ""

000e1e80 "C:\Documents and Settings\steve\"

000e1ec0 ""

000e1e80 "C:\Documents and Settings\"

000e1e80 "C:\Documents and Settings\"

000e1e80 "C:\"

00fee68c "C:\Documents and Settings\steve\"

00fee6cc "Desktop\ntoskrnl.pdb"

0007d000 "C:\Documents and Settings\All Us"

0007d040 "ers\Desktop\Far Out Field Trips."

0007d080 "lnk"

Cool – some rudimentary logging. You could fancy it up a bit and dump the stack each time as well by inserting ‘kL’ into it like

"du poi(ebp+8);kL;g"

And you get something like :

0007d000 "C:\Documents and Settings\All Us"

0007d040 "ers\Desktop\Camtasia Studio 2.ln"

0007d080 "k"

ChildEBP RetAddr

0007cb0c 77f67faf kernel32!CreateFileW

0007cd50 77f7a1aa SHLWAPI!CreateFileWrapW+0x73

0007cd88 7ca05b66 SHLWAPI!SHCreateStreamOnFileEx+0x48

0007cfc8 7ca05b17 SHELL32!CShellLink::_LoadFromFile+0x4c

0007cfd4 7c9fd574 SHELL32!CShellLink::Load+0x1e

0007d20c 7c9fd847 SHELL32!CFSFolder::_HandlerCreateInstance+0x7e

0007d4c4 7c9efc8e SHELL32!CFSFolder::_LoadHandler+0xcf

0007d4f4 7ca34d8a SHELL32!CFSFolder::GetUIObjectOf+0x261

0007d51c 7ca34d56 SHELL32!CDesktopFolder::_GetItemUIObject+0x31

0007d54c 7ca2d1b6 SHELL32!CDesktopFolder::GetUIObjectOf+0x110

0007d588 763dad01 SHELL32!CRegFolder::GetUIObjectOf+0x28c

0007d5c0 763b9df3 comdlg32!CFileOpenBrowser::ResolveLink+0x34

0007d5d8 763b4a21 comdlg32!CFileOpenBrowser::GetLinkStatus+0x26

0007d80c 763b4999 comdlg32!CFileOpenBrowser::LinkMatchSpec+0x55

0007d828 7c9f7dd1 comdlg32!CFileOpenBrowser::IncludeObject+0xd2

0007d83c 7c9f7d87 SHELL32!CDefView::_IncludeObject+0x49

0007d888 7c9f7c2b SHELL32!CDefView::_AddObject+0x19

0007d8b0 7c9f7bab SHELL32!CDefviewEnumTask::_FilterDPAs+0xdc

0007d8d0 7c9f7e2e SHELL32!CDefviewEnumTask::FillObjectsDoneToView+0xbd

0007d8e8 7c9f763e SHELL32!CDefView::FillDone+0x57

0007d000 "C:\Documents and Settings\All Us"

0007d040 "ers\Desktop\Far Out Field Trips."

0007d080 "lnk"

ChildEBP RetAddr

0007cb0c 77f67faf kernel32!CreateFileW

0007cd50 77f7a1aa SHLWAPI!CreateFileWrapW+0x73

0007cd88 7ca05b66 SHLWAPI!SHCreateStreamOnFileEx+0x48

0007cfc8 7ca05b17 SHELL32!CShellLink::_LoadFromFile+0x4c

0007cfd4 7c9fd574 SHELL32!CShellLink::Load+0x1e

0007d20c 7c9fd847 SHELL32!CFSFolder::_HandlerCreateInstance+0x7e

0007d4c4 7c9efc8e SHELL32!CFSFolder::_LoadHandler+0xcf

0007d4f4 7ca34d8a SHELL32!CFSFolder::GetUIObjectOf+0x261

0007d51c 7ca34d56 SHELL32!CDesktopFolder::_GetItemUIObject+0x31

0007d54c 7ca2d1b6 SHELL32!CDesktopFolder::GetUIObjectOf+0x110

0007d588 763dad01 SHELL32!CRegFolder::GetUIObjectOf+0x28c

0007d5c0 763b9df3 comdlg32!CFileOpenBrowser::ResolveLink+0x34

0007d5d8 763b4a21 comdlg32!CFileOpenBrowser::GetLinkStatus+0x26

0007d80c 763b4999 comdlg32!CFileOpenBrowser::LinkMatchSpec+0x55

0007d828 7c9f7dd1 comdlg32!CFileOpenBrowser::IncludeObject+0xd2

0007d83c 7c9f7d87 SHELL32!CDefView::_IncludeObject+0x49

0007d888 7c9f7c2b SHELL32!CDefView::_AddObject+0x19

0007d8b0 7c9f7bab SHELL32!CDefviewEnumTask::_FilterDPAs+0xdc

0007d8d0 7c9f7e2e SHELL32!CDefviewEnumTask::FillObjectsDoneToView+0xbd

0007d8e8 7c9f763e SHELL32!CDefView::FillDone+0x57

Anyway – next time we will move on to some more interesting uses for breakpoints..

Spatdsg