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: http://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

 

 

[~Threadbp[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:

 

[~Threadbp[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