Post

Useful Pwndbg & WinDbg Commands & IDA Pro Scripts

Symchk

1
 C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symchk.exe /s srv*c:\SYMBOLS*https://msdl.microsoft.com/download/symbols C:\Windows\System32\*.dll

Windbg to Pwndbg

Thanks to the Pwndbg dev team, users coming from Windbg will find pwndbg quite handy with the db, dt, dq, dq, etc... flags in Pwndbg. I really like the dt flag that will print out the type given a variable name.

I also like ptype command which will print the type of the variable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pwndbg> ptype fast_reload_t
type = struct fast_reload_s {
    FastReloadMemoryMode mode;
    shadow_memory_t *shadow_memory_state;
    snapshot_page_blocklist_t *blocklist;
    nyx_fdl_t *fdl_state;
    nyx_dirty_ring_t *dirty_ring_state;
    nyx_fdl_user_t *fdl_user_state;
    nyx_device_state_t *device_state;
    nyx_block_t *block_state;
    _Bool root_snapshot_created;
    _Bool incremental_snapshot_enabled;
    nyx_coverage_bitmap_copy_t *bitmap_copy;
    uint32_t dirty_pages;
}

info locals is another good one that can list Local variables of the current stack frame.

Useful Windbg command

Finding dispatcher object (Event, mutex, etc…)

  • Finding the usermode process
    1
    
    !process 0 0 lsass.exe
    
  • After finding the process address, list threads info and check those DISPATCHER_OBJECT
    1
    
    !process ffff8005bd42c080 6
    

  • Checking the DISPATCHER_OBJECT HEADER
    1
    
    dt nt!_DISPATCHER_HEADER ffff8005b84bd5a0
    

Finding the object with the name

  • Given a object name
    1
    2
    3
    4
    5
    
      kd> !object \SECURITY\LSA_AUTHENTICATION_INITIALIZED
      Object: ffff8005b84bd5a0  Type: (ffff8005b84c1f00) Event
          ObjectHeader: ffff8005b84bd570 (new version)
          HandleCount: 1  PointerCount: 32770
          Directory Object: ffffcc0a23c1c770  Name: LSA_AUTHENTICATION_INITIALIZED   
    
  • Highlight the Object address by Crtl + Left Click on the address ffff8005b84bd5a0

  • Search the handle table !findhandle ffff8005b84bd5a0

  • Validate the handle
  • Directory object

Checking Nt!_KTHREAD for objects waiting

1
2
3
4
5
6
7
kd> dx -id 0,0,ffff8005bd42c080 -r1 ((ntdll!_KTHREAD *)0xffff8005bd393080)
((ntdll!_KTHREAD *)0xffff8005bd393080)                 : 0xffff8005bd393080 [Type: _KTHREAD *]
	...
    [+0x0c8] WaitStatus       : 0 [Type: __int64]
    [+0x0d0] WaitBlockList    : 0xffff8005bd3931c0 [Type: _KWAIT_BLOCK *]
	...
	
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
kd> dt _KWAIT_BLOCK 0xffff8005bd3931c0
ntdll!_KWAIT_BLOCK
   +0x000 WaitListEntry    : _LIST_ENTRY [ 0xffff8005`b84bd5a8 - 0xffff8005`b84bd5a8 ]
   +0x010 WaitType         : 0x1 ''
   +0x011 BlockState       : 0x4 ''
   +0x012 WaitKey          : 0
   +0x014 SpareLong        : 0n671
   +0x018 Thread           : 0xffff8005`bd393080 _KTHREAD - THREAD RUNNING HARNESS
   +0x018 NotificationQueue : 0xffff8005`bd393080 _KQUEUE
   +0x020 Object           : 0xffff8005`b84bd5a0 Void - EVENT Object: LSA_AUTHENTICATION_INITIALIZED
   +0x028 SparePtr         : (null) 

kd> !object 0xffff8005`b84bd5a0
Object: ffff8005b84bd5a0  Type: (ffff8005b84c1f00) Event
    ObjectHeader: ffff8005b84bd570 (new version)
    HandleCount: 1  PointerCount: 32770
    Directory Object: ffffcc0a23c1c770  Name: LSA_AUTHENTICATION_INITIALIZED


Checking NT!_DISPACTHER_HEADER for thread waiting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
dt -r1 nt!_KEVENT ffff8005b84bd5a0 () Recursive: [ -r1 -r2 -r ] Verbose Normal dt
==================================================================================
   +0x000 Header               : _DISPATCHER_HEADER
      +0x000 Lock                 : 0n33947648 (0x2060000)
      +0x000 LockNV               : 0n33947648 (0x2060000)
      +0x000 Type                 : 0 ''
      +0x001 Signalling           : 0 ''
      +0x002 Size                 : 0x6 ''
      +0x003 Reserved1            : 0x2 ''
      +0x000 TimerType            : 0 ''
      +0x001 TimerControlFlags    : 0 ''
      +0x001 Absolute             : 0y0
      +0x001 Wake                 : 0y0
      +0x001 EncodedTolerableDelay : 0y000000 (0)
      +0x002 Hand                 : 0x6 ''
      +0x003 TimerMiscFlags       : 0x2 ''
      +0x003 Index                : 0y000010 (0x2)
      +0x003 Inserted             : 0y0
      +0x003 Expired              : 0y0
      +0x000 Timer2Type           : 0 ''
      +0x001 Timer2Flags          : 0 ''
      +0x001 Timer2Inserted       : 0y0
      +0x001 Timer2Expiring       : 0y0
      +0x001 Timer2CancelPending  : 0y0
      +0x001 Timer2SetPending     : 0y0
      +0x001 Timer2Running        : 0y0
      +0x001 Timer2Disabled       : 0y0
      +0x001 Timer2ReservedFlags  : 0y00 (0n0)
      +0x002 Timer2ComponentId    : 0x6 ''
      +0x003 Timer2RelativeId     : 0x2 ''
      +0x000 QueueType            : 0 ''
      +0x001 QueueControlFlags    : 0 ''
      +0x001 Abandoned            : 0y0
      +0x001 DisableIncrement     : 0y0
      +0x001 QueueReservedControlFlags : 0y000000 (0)
      +0x002 QueueSize            : 0x6 ''
      +0x003 QueueReserved        : 0x2 ''
      +0x000 ThreadType           : 0 ''
      +0x001 ThreadReserved       : 0 ''
      +0x002 ThreadControlFlags   : 0x6 ''
      +0x002 CycleProfiling       : 0y0
      +0x002 CounterProfiling     : 0y1
      +0x002 GroupScheduling      : 0y1
      +0x002 AffinitySet          : 0y0
      +0x002 Tagged               : 0y0
      +0x002 EnergyProfiling      : 0y0
      +0x002 SchedulerAssist      : 0y0
      +0x002 ThreadReservedControlFlags : 0y0
      +0x003 DebugActive          : 0x2 ''
      +0x003 ActiveDR7            : 0y0
      +0x003 Instrumented         : 0y1
      +0x003 Minimal              : 0y0
      +0x003 Reserved4            : 0y00 (0n0)
      +0x003 AltSyscall           : 0y0
      +0x003 UmsScheduled         : 0y0
      +0x003 UmsPrimary           : 0y0
      +0x000 MutantType           : 0 ''
      +0x001 MutantSize           : 0 ''
      +0x002 DpcActive            : 0x6 ''
      +0x003 MutantReserved       : 0x2 ''
      +0x004 SignalState          : 0n0
      +0x008 WaitListHead         : _LIST_ENTRY [ 0xffff8005`bd3931c0 - 0xffff8005`bd3931c0 ] [EMPTY OR 1 ELEMENT]


kd> dt _KWAIT_BLOCK  0xffff8005`bd3931c0
ntdll!_KWAIT_BLOCK
   +0x000 WaitListEntry    : _LIST_ENTRY [ 0xffff8005`b84bd5a8 - 0xffff8005`b84bd5a8 ]
   +0x010 WaitType         : 0x1 ''
   +0x011 BlockState       : 0x4 ''
   +0x012 WaitKey          : 0
   +0x014 SpareLong        : 0n671
   +0x018 Thread           : 0xffff8005`bd393080 _KTHREAD
   +0x018 NotificationQueue : 0xffff8005`bd393080 _KQUEUE
   +0x020 Object           : 0xffff8005`b84bd5a0 Void
   +0x028 SparePtr         : (null) 

Running threads at the time of crashes

1
2: kd> !running-t

Search through all callstacks for modules

1
!stacks 0 myfault

IDA Pro Scripts

Collecting all functions called within a function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import ida_funcs
import idautils
import idaapi
import idc

def extract_function_name(name):
    if '@@' in name:
        return name.split('@@')[0]
    return name


def list_function_calls_within(func_ea):
    func = ida_funcs.get_func(func_ea)
    if func is None:
        print(f"No function found at 0x{func_ea:08X}")
        return

    func_name = ida_funcs.get_func_name(idc.here())
    print(f"Function calls within function {func_name} at 0x{func_ea:08X}:")
    for head in idautils.FuncItems(function_address):
        for insn in idautils.XrefsFrom(head, idaapi.XREF_FAR):
            if insn.type == idaapi.fl_CN:
                called_func = ida_funcs.get_func(insn.to)
                if called_func:
                    if "WPP" not in ida_funcs.get_func_name(insn.to):  
                        print(f"0x{insn.to:08X}: {extract_function_name(ida_funcs.get_func_name(insn.to))}")

# Replace 0x12345678 with the address of the function you want to analyze
function_address = idc.here()
list_function_calls_within(function_address)

This post is licensed under CC BY 4.0 by the author.