Log in

View Full Version : How do DLL breakpoints work, especially those in system DLLs?


romkyns
September 14th, 2011, 10:31
A conventional breakpoint is set by replacing an opcode with "int 3". This is fine in an EXE file, but how exactly does this work in a DLL? If I understand correctly, DLLs map the same memory into several processes' address space - this being their main attraction, as this uses the physical memory only once. But surely then an "int 3" instruction would be seen and executed in all processes that share a DLL?

One theory I had was that they are mapped with copy-on-write semantics, where the OS transparently makes a copy of the modified page, and then makes the change. Presumably this would require that the first write faults, the OS makes the copy and then repeats the write invisibly.

If this is so, can I somehow tell if a particular DLL page is "real" or "copied", in OllyDbg? If this is way off, how do DLL breakpoints *actually* work?

Aimless
September 14th, 2011, 12:18
...you could look at something called a CONTEXT.

Find out how it works, what its structure is like and you should be good to go.

Have Phun

blabberer
September 14th, 2011, 14:55
if you have set a bp on ollydbg and you wish to see it from the same ollydbg it is not feasible if you come to think of it

but you can see the byte 0xcc set if you view the debuggees copy of dll from another debugger

windows maintains a copy of dll in every process and only the process own copy will have the modificiations and the page that holds the copy will be marked DIRTY is the term iirc

see in ollydbg i set this bp in ntdll
Code:

Breakpoints
Address Module Active Disassembly Comment
00401000 msgbox.<ModuleEntryPoint> msgbox One-shot PUSH 0
7C90D0AE ntdll.ZwCreateFile ntdll Always MOV EAX, 25


ollydbg doesnt show 0xcc

7C90D0AE ntdll.ZwCreateFile B8 25000000 MOV EAX, 25





if i use windbg local kernel debugging facility to view the debuggeee msgbox.exe

i can see 0xcc

Code:

lkd> !process 0 0 msgbox.exe
PROCESS 85d1b8f8 SessionId: 0 Cid: 0258 Peb: 7ffd8000 ParentCid: 08bc
DirBase: 0f7c04e0 ObjectTable: e278a098 HandleCount: 5.
Image: msgbox.exe

lkd> .process /p /r 85d1b8f8
Implicit process is now 85d1b8f8
Loading User Symbols
.......
lkd> lm m ntdll*
start end module name
7c900000 7c9b2000 ntdll (pdb symbols) f:\symbols\ntdll.pdb\6992F4DAF4B144068D78669D6CB5D2072\ntdll.pdb
lkd> db 7c90d0ae l10
7c90d0ae cc 25 00 00 00 ba 00 03-fe 7f ff 12 c2 2c 00 90 .%...........,.. virtual address
lkd> !vtop 0f7c04e0 7c90d0ae
X86VtoP: Virt 7c90d0ae, pagedir f7c04e0
X86VtoP: PAE PDPE f7c04e8 - 0000000031353001
X86VtoP: PAE PDE 31353f20 - 000000002abdf067
X86VtoP: PAE PTE 2abdf868 - 0000000038801025
X86VtoP: PAE Mapped phys 388010ae
Virtual address 7c90d0ae translates to physical address 388010ae.
lkd> !db 388010ae l10
*** WARNING: Unable to verify checksum for F:\masm32\icztutes\tute02\msgbox.exe
*** ERROR: Module load completed but symbols could not be loaded for F:\masm32\icztutes\tute02\msgbox.exe
#388010ae cc 25 00 00 00 ba 00 03-fe 7f ff 12 c2 2c 00 90 .%...........,.. physical page

Kayaker
September 14th, 2011, 23:13
Another possibility for detecting a copy-on-write page - use QueryWorkingSet and check the Shared and ShareCount fields of the returned data. For code sections of system dlls the Shared bit should be set, meaning the page is shareable. If it has been cleared it's supposed to mean that the page has been written to (i.e. a breakpoint set) and copy-on-write has taken place.

As described in the entry for VirtualQueryEx:

Quote:

If a shared copy-on-write page is modified, it becomes private to the process that modified the page. However, the VirtualQueryEx function will continue to report such pages as MEM_MAPPED (for data views) or MEM_IMAGE (for executable image views) rather than MEM_PRIVATE. To detect whether copy-on-write has occurred for a specific page, either access the page or lock it using the VirtualLock function to make sure the page is resident in memory, then use the QueryWorkingSet or QueryWorkingSetEx function to check the Shared bit in the extended working set information for the page. If the Shared bit is clear, the page is private.



http://msdn.microsoft.com/en-us/library/ms684946.aspx
http://msdn.microsoft.com/en-us/library/aa366907.aspx



I haven't tested the above assumption, but I think we can see the results with Sysinternals VMMap. In the first snapshot below we're looking at the memory details of Notepad loaded into Ollydbg - without any breakpoints set. Notice that Private WS (the amount of physical memory assigned to the type or region that cannot be shared with other processes) for the code sections of kernel32.dll and ntdll.dll is empty. In other words, the .text sections are still virgin. (look for the mouse pointer in the snapshot)

In the second snapshot I have set regular breakpoints on an API in both kernel32 and ntdll for the loaded Notepad, and refreshed VMMap. Notice that there is now an entry for Private WS for the .text section for both dlls. That looks to me like an indicator that copy-on-write has occured because of the breakpoints. There are other changes as well, but Private WS seems to be the clearest sign.

Note that this won't work if a page has already been made private because of a previous copy-on-write event, i.e. Comodo firewall automatically hooks a couple of kernel32 API's in the Notepad debugee process when it starts, and any subsequent COW because of a breakpoint setting can't be discerned using VMMap. (I ran those tests on a basic XP system under VM)

Kayaker

24912492

romkyns
September 15th, 2011, 17:45
Thanks everyone, especially Kayaker - exactly what I was after.