Monday, May 23, 2016

Chrome stops rendering on Ubuntu/Mint linux on a VirtualBox upgrade 5.0.20

Chrome fails to render and we may see following in the VBox Logs

00:01:30.482694 VMMDev: SetVideoModeHint: Got a video mode hint (1366x768x32)@(0x0),(1;0) at 0
00:01:30.482707 GUI: UISession::sltAdditionsChange: GA state change event came, notifying listeners.
00:04:33.874279 OpenGL Info: Render SPU: GL_VENDOR:   Intel
00:04:33.874299 OpenGL Info: Render SPU: GL_RENDERER: Intel(R) HD Graphics 4400
00:04:33.874306 OpenGL Info: Render SPU: GL_VERSION:  4.3.0 - Build 10.18.15.4256
00:04:33.874311 OpenGL Info: Render SPU: GL_EXTENSIONS: GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_blend_color GL_EXT_abgr GL_EXT_texture3D GL_EXT_clip_volume_hint GL_EXT_compiled_vertex_array GL_SGIS_texture_edge_clamp GL_SGIS_generate_mipmap GL_EXT_draw_range_elements GL_SGIS_texture_lod GL_EXT_rescale_normal GL_EXT_packed_pixels GL_EXT_texture_edge_clamp GL_EXT_separate_specular_color GL_ARB_multitexture GL_ARB_map_buffer_alignment GL_ARB_conservative_depth GL_EXT_texture_env_combine GL_EXT_bgra GL_EXT_blend_func_separate GL_EXT_secondary_color GL_EXT_fog_coord GL_EXT_texture_env_add GL_ARB_texture_cube_map GL_ARB_transpose_matrix GL_ARB_internalformat_query GL_ARB_internalformat_query2 GL_ARB_texture_env_add GL_IBM_texture_mirrored_repeat GL_ARB_texture_mirrored_repeat GL_EXT_multi_draw_arrays GL_SUN_multi_draw_arrays GL_NV_blend_square GL_ARB_texture_compression GL_3DFX_texture_compression_FXT1 GL_EXT_texture_filter_anisotropic GL_ARB_texture_border_clamp GL_ARB_point_parameters GL_ARB_texture_env_combine GL_ARB_texture_env_dot3 GL_ARB_texture_env_crossbar GL_EXT_texture_compression_s3tc GL_ARB_shadow GL_ARB_window_pos GL_EXT_shadow_funcs GL_EXT_stencil_wrap GL_ARB_vertex_program GL_EXT_texture_rectangle GL_ARB_fragment_program GL_EXT_stencil_two_side GL_ATI_separate_stencil GL_ARB_vertex_buffer_object GL_EXT_texture_lod_bias GL_ARB_occlusion_query GL_ARB_fragment_shader GL_ARB_shader_objects GL_ARB_shading_language_100 GL_ARB_texture_non_power_of_two GL_ARB_vertex_shader GL_NV_texgen_reflection GL_ARB_point_sprite GL_ARB_fragment_program_shadow GL_EXT_blend_equation_separate GL_ARB_depth_texture GL_ARB_texture_rectangle GL_ARB_draw_buffers GL_ARB_color_buffer_float GL_ARB_half_float_pixel GL_ARB_texture_float GL_ARB_pixel_buffer_object GL_EXT_framebuffer_object GL_ARB_draw_instanced GL_ARB_half_float_vertex GL_ARB_occlusion_query2 GL_EXT_draw_buffers2 GL_WIN_swap_hint GL_EXT_texture_sRGB GL_ARB_multisample GL_EXT_packed_float GL_EXT_texture_shared_exponent GL_ARB_texture_rg GL_ARB_texture_compression_rgtc GL_NV_conditional_render GL_ARB_texture_swizzle GL_EXT_texture_swizzle GL_ARB_texture_gather GL_ARB_sync GL_ARB_cl_event GL_ARB_framebuffer_sRGB GL_EXT_packed_depth_stencil GL_ARB_depth_buffer_float GL_EXT_transform_feedback GL_ARB_transform_feedback2 GL_ARB_draw_indirect GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_ARB_framebuffer_object GL_ARB_framebuffer_no_attachments GL_EXT_texture_array GL_EXT_texture_integer GL_ARB_map_buffer_range GL_ARB_texture_buffer_range GL_EXT_texture_snorm GL_ARB_blend_func_extended GL_INTEL_performance_query GL_ARB_copy_buffer GL_ARB_sampler_objects GL_NV_primitive_restart GL_ARB_seamless_cube_map GL_ARB_seamless_cubemap_per_texture GL_ARB_uniform_buffer_object GL_ARB_depth_clamp GL_ARB_vertex_array_bgra GL_ARB_shader_bit_encoding GL_ARB_draw_buffers_blend GL_ARB_geometry_shader4 GL_EXT_geometry_shader4 GL_ARB_texture_query_lod GL_ARB_explicit_attrib_location GL_ARB_draw_elements_base_vertex GL_EXT_shader_integer_mix GL_ARB_instanced_arrays GL_ARB_base_instance GL_ARB_fragment_coord_conventions GL_EXT_gpu_program_parameters GL_ARB_texture_buffer_object_rgb32 GL_ARB_compatibility GL_ARB_texture_rgb10_a2ui GL_ARB_texture_multisample GL_ARB_vertex_type_2_10_10_10_rev GL_ARB_vertex_type_10f_11f_11f_rev GL_ARB_timer_query GL_ARB_tessellation_shader GL_ARB_vertex_array_object GL_ARB_provoking_vertex GL_ARB_sample_shading GL_ARB_texture_cube_map_array GL_EXT_gpu_shader4 GL_ARB_gpu_shader5 GL_ARB_gpu_shader_fp64 GL_INTEL_fragment_shader_ordering GL_EXT_clip_control GL_ARB_shader_subroutine GL_ARB_transform_feedback3 GL_ARB_get_program_binary GL_ARB_separate_shader_objects GL_ARB_shader_precision GL_ARB_vertex_attrib_64bit GL_ARB_viewport_array GL_ARB_transform_feedback_instanced GL_ARB_compressed_texture_pixel_storage GL_ARB_shader_atomic_counters GL_ARB_shading_language_packing GL_ARB_shader_image_load_store GL_ARB_shading_language_420pack GL_ARB_texture_storage GL_EXT_texture_storage GL_ARB_compute_shader GL_ARB_vertex_attrib_binding GL_ARB_texture_view GL_ARB_fragment_layer_viewport GL_ARB_multi_draw_indirect GL_ARB_program_interface_query GL_ARB_shader_image_size GL_ARB_shader_storage_buffer_object GL_ARB_texture_storage_multisample GL_ARB_buffer_storage GL_AMD_vertex_shader_layer GL_AMD_vertex_shader_viewport_index GL_ARB_query_buffer_object GL_EXT_polygon_offset_clamp GL_ARB_clear_texture GL_ARB_texture_mirror_clamp_to_edge GL_ARB_debug_output GL_ARB_enhanced_layouts GL_KHR_debug GL_ARB_arrays_of_arrays GL_ARB_texture_query_levels GL_ARB_invalidate_subdata GL_ARB_clear_buffer_object GL_INTEL_map_texture GL_ARB_texture_compression_bptc GL_ARB_ES2_compatibility GL_ARB_ES3_compatibility GL_ARB_robustness GL_ARB_robust_buffer_access_behavior GL_EXT_texture_sRGB_decode GL_ARB_copy_image GL_KHR_blend_equation_advanced GL_EXT_direct_state_access GL_ARB_stencil_texturing GL_ARB_texture_stencil8 GL_ARB_explicit_uniform_location GL_ARB_multi_bind GL_ARB_indirect_parameters
00:04:33.950645 OpenGL Info: Render SPU: GL_VENDOR:   Intel
00:04:33.950659 OpenGL Info: Render SPU: GL_RENDERER: Intel(R) HD Graphics 4400
00:04:33.950663 OpenGL Info: Render SPU: GL_VERSION:  4.3.0 - Build 10.18.15.4256
00:04:33.950666 OpenGL Info: Render SPU: GL_EXTENSIONS: GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_blend_color GL_EXT_abgr GL_EXT_texture3D GL_EXT_clip_volume_hint GL_EXT_compiled_vertex_array GL_SGIS_texture_edge_clamp GL_SGIS_generate_mipmap GL_EXT_draw_range_elements GL_SGIS_texture_lod GL_EXT_rescale_normal GL_EXT_packed_pixels GL_EXT_texture_edge_clamp GL_EXT_separate_specular_color GL_ARB_multitexture GL_ARB_map_buffer_alignment GL_ARB_conservative_depth GL_EXT_texture_env_combine GL_EXT_bgra GL_EXT_blend_func_separate GL_EXT_secondary_color GL_EXT_fog_coord GL_EXT_texture_env_add GL_ARB_texture_cube_map GL_ARB_transpose_matrix GL_ARB_internalformat_query GL_ARB_internalformat_query2 GL_ARB_texture_env_add GL_IBM_texture_mirrored_repeat GL_ARB_texture_mirrored_repeat GL_EXT_multi_draw_arrays GL_SUN_multi_draw_arrays GL_NV_blend_square GL_ARB_texture_compression GL_3DFX_texture_compression_FXT1 GL_EXT_texture_filter_anisotropic GL_ARB_texture_border_clamp GL_ARB_point_parameters GL_ARB_texture_env_combine GL_ARB_texture_env_dot3 GL_ARB_texture_env_crossbar GL_EXT_texture_compression_s3tc GL_ARB_shadow GL_ARB_window_pos GL_EXT_shadow_funcs GL_EXT_stencil_wrap GL_ARB_vertex_program GL_EXT_texture_rectangle GL_ARB_fragment_program GL_EXT_stencil_two_side GL_ATI_separate_stencil GL_ARB_vertex_buffer_object GL_EXT_texture_lod_bias GL_ARB_occlusion_query GL_ARB_fragment_shader GL_ARB_shader_objects GL_ARB_shading_language_100 GL_ARB_texture_non_power_of_two GL_ARB_vertex_shader GL_NV_texgen_reflection GL_ARB_point_sprite GL_ARB_fragment_program_shadow GL_EXT_blend_equation_separate GL_ARB_depth_texture GL_ARB_texture_rectangle GL_ARB_draw_buffers GL_ARB_color_buffer_float GL_ARB_half_float_pixel GL_ARB_texture_float GL_ARB_pixel_buffer_object GL_EXT_framebuffer_object GL_ARB_draw_instanced GL_ARB_half_float_vertex GL_ARB_occlusion_query2 GL_EXT_draw_buffers2 GL_WIN_swap_hint GL_EXT_texture_sRGB GL_ARB_multisample GL_EXT_packed_float GL_EXT_texture_shared_exponent GL_ARB_texture_rg GL_ARB_texture_compression_rgtc GL_NV_conditional_render GL_ARB_texture_swizzle GL_EXT_texture_swizzle GL_ARB_texture_gather GL_ARB_sync GL_ARB_cl_event GL_ARB_framebuffer_sRGB GL_EXT_packed_depth_stencil GL_ARB_depth_buffer_float GL_EXT_transform_feedback GL_ARB_transform_feedback2 GL_ARB_draw_indirect GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_ARB_framebuffer_object GL_ARB_framebuffer_no_attachments GL_EXT_texture_array GL_EXT_texture_integer GL_ARB_map_buffer_range GL_ARB_texture_buffer_range GL_EXT_texture_snorm GL_ARB_blend_func_extended GL_INTEL_performance_query GL_ARB_copy_buffer GL_ARB_sampler_objects GL_NV_primitive_restart GL_ARB_seamless_cube_map GL_ARB_seamless_cubemap_per_texture GL_ARB_uniform_buffer_object GL_ARB_depth_clamp GL_ARB_vertex_array_bgra GL_ARB_shader_bit_encoding GL_ARB_draw_buffers_blend GL_ARB_geometry_shader4 GL_EXT_geometry_shader4 GL_ARB_texture_query_lod GL_ARB_explicit_attrib_location GL_ARB_draw_elements_base_vertex GL_EXT_shader_integer_mix GL_ARB_instanced_arrays GL_ARB_base_instance GL_ARB_fragment_coord_conventions GL_EXT_gpu_program_parameters GL_ARB_texture_buffer_object_rgb32 GL_ARB_compatibility GL_ARB_texture_rgb10_a2ui GL_ARB_texture_multisample GL_ARB_vertex_type_2_10_10_10_rev GL_ARB_vertex_type_10f_11f_11f_rev GL_ARB_timer_query GL_ARB_tessellation_shader GL_ARB_vertex_array_object GL_ARB_provoking_vertex GL_ARB_sample_shading GL_ARB_texture_cube_map_array GL_EXT_gpu_shader4 GL_ARB_gpu_shader5 GL_ARB_gpu_shader_fp64 GL_INTEL_fragment_shader_ordering GL_EXT_clip_control GL_ARB_shader_subroutine GL_ARB_transform_feedback3 GL_ARB_get_program_binary GL_ARB_separate_shader_objects GL_ARB_shader_precision GL_ARB_vertex_attrib_64bit GL_ARB_viewport_array GL_ARB_transform_feedback_instanced GL_ARB_compressed_texture_pixel_storage GL_ARB_shader_atomic_counters GL_ARB_shading_language_packing GL_ARB_shader_image_load_store GL_ARB_shading_language_420pack GL_ARB_texture_storage GL_EXT_texture_storage GL_ARB_compute_shader GL_ARB_vertex_attrib_binding GL_ARB_texture_view GL_ARB_fragment_layer_viewport GL_ARB_multi_draw_indirect GL_ARB_program_interface_query GL_ARB_shader_image_size GL_ARB_shader_storage_buffer_object GL_ARB_texture_storage_multisample GL_ARB_buffer_storage GL_AMD_vertex_shader_layer GL_AMD_vertex_shader_viewport_index GL_ARB_query_buffer_object GL_EXT_polygon_offset_clamp GL_ARB_clear_texture GL_ARB_texture_mirror_clamp_to_edge GL_ARB_debug_output GL_ARB_enhanced_layouts GL_KHR_debug GL_ARB_arrays_of_arrays GL_ARB_texture_query_levels GL_ARB_invalidate_subdata GL_ARB_clear_buffer_object GL_INTEL_map_texture GL_ARB_texture_compression_bptc GL_ARB_ES2_compatibility GL_ARB_ES3_compatibility GL_ARB_robustness GL_ARB_robust_buffer_access_behavior GL_EXT_texture_sRGB_decode GL_ARB_copy_image GL_KHR_blend_equation_advanced GL_EXT_direct_state_access GL_ARB_stencil_texturing GL_ARB_texture_stencil8 GL_ARB_explicit_uniform_location GL_ARB_multi_bind GL_ARB_indirect_parameters
00:04:41.012183 OpenGL Warning: CRServer: context sharing not implemented.
00:04:42.433900 OHCI#0: Lagging too far behind, not trying to catch up anymore. Expect glitches with USB devices
00:04:44.831357 OpenGL Warning: CRServer: context sharing not implemented.
00:04:44.882475 OpenGL Warning: CRServer: context sharing not implemented.
00:04:46.465129 OpenGL Warning: CRServer: context sharing not implemented.
00:04:46.573323 OpenGL Warning: CRServer: context sharing not implemented.
.... <SNIP>
00:33:47.689583 OpenGL Warning: CRServer: context sharing not implemented.
00:33:47.724835 OpenGL Warning: CRServer: context sharing not implemented.
00:33:48.746898 OpenGL Warning: cleaning gl error (0x502), ignoring.. (1 out of 5) ..
00:33:48.763229 OpenGL Warning: cleaning gl error (0x502), ignoring.. (2 out of 5) ..
00:33:48.780733 OpenGL Warning: cleaning gl error (0x502), ignoring.. (3 out of 5) ..
00:33:48.879441 OpenGL Warning: cleaning gl error (0x502), ignoring.. (4 out of 5) ..
00:33:48.964728 OpenGL Warning: cleaning gl error (0x502), ignoring.. (5 out of 5) ..
00:36:09.052959 OpenGL Warning: CRServer: context sharing not implemented.
00:36:09.096412 OpenGL Warning: CRServer: context sharing not implemented.
00:36:09.117746 OpenGL Warning: CRServer: context sharing not implemented.

Not much I could do about it but if we use the command line switch --enable-gpu-rasterization=disabled with chromium browser (not google-chrome-table) it works fine. This should get rid of the GPU rendering most probably.

The issue may be due to the VBox;s new VM additions for linux however we still need to dig further on that part.


Wednesday, December 26, 2012

Examining Netstat - Windbg Adventures

 

Here is a scenario which helps us understanding how this stuff really works internally. I generally take a longer aproach since the application is unknown or atleast I don't have the source code for this piece of *app. So we start with finding main.


Finding Main

We will use the x (examine command) to enumerate symbols. (assuming you have the Symbol paths set right)
0:000> x netstat!*main*
00000000`ff1f1258 netstat!_imp___getmainargs = <no type information>
00000000`ff1f1634 netstat!main = <no type information>
00000000`ff1f7100 netstat!_native_dllmain_reason = <no type information>
00000000`ff1f5800 netstat!mainCRTStartup = <no type information>
so we have the main netstat!main but notice the other calls which also have main in their name. Well getting back to the old Galvin Schilbert days it says "OS provides the environment for execution". So here it is netstat!mainCRTStartup which initializes the runtime. What do we really meain by intiailzing the runtime ??? Well  you can read more from the MSVCR source code which is generally there with any visual studio installs. The runtime is responsible for initializing the CRT heap (used by malloc to allocate dynamic memory etc.) and other datastructures.
So the mainCRTStartup Calls the application's main function. as can be seen from the following stack (use kvn or kb or k for stack)
0:000> ~*kvn
.  0  Id: 2020.23c0 Suspend: 1 Teb: 000007ff`fffdd000 Unfrozen
 # Child-SP          RetAddr           : Args to Child                                                           : Call Site
00 00000000`0021fec8 00000000`ff5256b1 : 00000000`00000000 00000000`ff525809 01cde338`35926925 00000019`2c6dbbbd : netstat!main
01 00000000`0021fed0 00000000`76eb652d : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : netstat!K32GetModuleBaseNameA+0x19b
02 00000000`0021ff10 00000000`775ac521 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
03 00000000`0021ff40 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d
surprised .. !!!! yeah even I was .... WT**** happened here how did we get K32GetModuleBaseNameA calling the main. Where is the damn mainCRTStartup as we see it in the notpad or a simple casts sample I wrote for some experimentations
 # ChildEBP RetAddr  Args to Child             
00 0032f7dc 00b01248 00000001 004e2338 004e2380 casts!main (FPO: [Non-Fpo]) (CONV: cdecl) [d:\addy\projects\learncpp\casts.cpp @ 22]
01 0032f824 759a339a 7efde000 0032f870 77799ef2 casts!__tmainCRTStartup+0x10b (FPO: [Non-Fpo]) (CONV: cdecl) [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c @ 278]
02 0032f830 77799ef2 7efde000 75caaefe 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
03 0032f870 77799ec5 00b0129e 7efde000 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
04 0032f888 00000000 00b0129e 7efde000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

so the only difference in this case is I linked the CRT statically with this application which I generally do when I am building standalone applications so that they don't blow up because of side by side installations of the Runtime DLLs.
I guess we are going to explore this fact later on and check out more on or objective of understanding how netstat works.
so we know netstat!main is our guy. How ???? well get some C basics and intuition if you have that question.

Breaking In and follow the flow

Allright !!!  time for some action let's break-in and see how this main works out the connection. Now again we need to rely on the symbolic names of the function and some common sense to  progress through.  To set a break point we need a bp command (check the help file for variants of b* commands).
0:000> bp netsat!main
Hit the g command to continue and hit the break point
0:000> g
ModLoad: 000007fe`ff6b0000 000007fe`ff6de000   C:\Windows\system32\IMM32.DLL
ModLoad: 000007fe`ff780000 000007fe`ff889000   C:\Windows\system32\MSCTF.dll
Breakpoint 1 hit
netstat!main:
now we have two choices
1. Let's see what functions are called by main and pick n choose our next stop (breakpoint)
2.  step through the main (man this is a lengthy one)
Let's try the first one. "uf" is the unassemble function command in windbg. "uf /c" disassembles all the "call" instructions and shows us which functions are called by netstat!main. Following is the stripped output of uf /c which shows the calls which intersted me while debugging
0:000> uf /c netstat!main
 netstat!main+0x52e (00000000`ff881b62):
    call to netstat!DoIP (00000000`ff88221c)
  netstat!main+0x53f (00000000`ff881b73):
    call to netstat!DoIP (00000000`ff88221c)
  netstat!main+0x550 (00000000`ff881b84):
    call to netstat!DoICMP (00000000`ff8823a4)
  netstat!main+0x560 (00000000`ff881b94):
    call to netstat!DoICMP (00000000`ff8823a4)
  netstat!main+0x571 (00000000`ff881ba5):
    call to netstat!DoTCP (00000000`ff882278)
  netstat!main+0x582 (00000000`ff881bb6):
    call to netstat!DoTCP (00000000`ff882278)
  netstat!main+0x593 (00000000`ff881bc7):
    call to netstat!DoUDP (00000000`ff8822d4)
  netstat!main+0x5a4 (00000000`ff881bd8):
    call to netstat!DoUDP (00000000`ff8822d4)
  netstat!main+0x5e9 (00000000`ff881c1d):
    call to netstat!DoConnections (00000000`ff882428)




So we see calls like DoTCP, DoIP etc. I tried using DoTCP as a call but the program exitted. So I decided to step through and see which one do we call and we see while stepping through using "p" command (step over the calls) and the stepping in using "t" trace command.

netstat!main+0x5e0:
00000000`ff881c14 8bd3            mov     edx,ebx
0:000>
netstat!main+0x5e2:
00000000`ff881c16 418bcf          mov     ecx,r15d
0:000>
netstat!main+0x5e5:
00000000`ff881c19 89442420        mov     dword ptr [rsp+20h],eax ss:00000000`000ff5b0=00000000
0:000>
netstat!main+0x5e9:
00000000`ff881c1d e806080000      call    netstat!DoConnections (00000000`ff882428)
0:000> t
netstat!DoConnections:
00000000`ff882428 44894c2420      mov     dword ptr [rsp+20h],r9d ss:00000000`000ff5a8=000001b5
0:000> p
netstat!DoConnections+0x5:
00000000`ff88242d 89542410        mov     dword ptr [rsp+10h],edx ss:00000000`000ff598=00000000
0:000>
netstat!DoConnections+0x9:
00000000`ff882431 894c2408        mov     dword ptr [rsp+8],ecx ss:00000000`000ff590=000000ff
0:000>
netstat!DoConnections+0xd:
00000000`ff882435 53              push    rbx

We see we call the DoConnections Call in this case. The we disassemble the DoConnections call to see what's our next stop.

Breakpoint 1 hit
netstat!DoConnections:
00000000`ff522428 44894c2420      mov     dword ptr [rsp+20h],r9d ss:00000000`0021fb58=000001b5
0:000> kvn
 # Child-SP          RetAddr           : Args to Child                                                           : Call Site
00 00000000`0021fb38 00000000`ff521c22 : 00000000`000000ff 00000000`00000000 00000000`01cc6940 00000000`000001b5 : netstat!DoConnections
01 00000000`0021fb40 00000000`ff5256b1 : 00000000`00000000 00000000`ff525809 00000000`00000000 00000000`ff521340 : netstat!main+0x5ee
02 00000000`0021fed0 00000000`76eb652d : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : netstat!K32GetModuleBaseNameA+0x19b
03 00000000`0021ff10 00000000`775ac521 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0xd
04 00000000`0021ff40 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x1d

now doing that we have a lots of calls which deal with TCP and UDP tables, with or without the owner modules (netstat -b) would be the most probable candidate calling this.
but InternalGetTcpTable2 interests us more.

netstat!DoConnections+0x1ee (00000000`ff522616):
    call to netstat!InternalGetTcpTable2 (00000000`ff525c80)
  netstat!DoConnections+0x23d (00000000`ff522665):
 
so we disassemble this one and check how does it acquire the TCP table
so now we see

0:000> uf /c netstat!InternalGetTCPTable2
netstat!InternalGetTcpTable2 (00000000`ff525c80)
  IPHLPAPI!InternalGetTcpTable2+0x23 (000007fe`faabde8b):
    call to IPHLPAPI!InternalGetTable (000007fe`faabdc80)
there is only one call and this one actually looks like a public call to the IP Helper API documented in MSDN. Fair .. so let's look at the documentation
http://msdn.microsoft.com/en-us/library/windows/desktop/bb408406(v=vs.85).aspx
ULONG WINAPI GetTcpTable2(
  _Out_    PMIB_TCPTABLE2 TcpTable,
  _Inout_  PULONG SizePointer,
  _In_     BOOL Order
);

now  this is pretty much standard code. as documented in MSDN.
So Now WHAT??? we end here ??? nah .. we are suppose to understand how this piece works.
 

THE UNDOCUMENTED 


 Okay !! so we ended up in a call where there is no source or documentation in terms how this is going to flow. Disassembly to the rescue!!!

 0:000> uf /c IPHLPAPI!InternalGetTable
IPHLPAPI!InternalGetTable (000007fe`faabdc80)
  IPHLPAPI!InternalGetTable+0x3f (000007fe`faabdcbf):
    call to ntdll!RtlAllocateHeap (00000000`775d33a0)
  IPHLPAPI!InternalGetTable+0x5e (000007fe`faabdcde):
    unresolvable call: call    qword ptr [rsp+78h]
  IPHLPAPI!InternalGetTable+0x76 (000007fe`faabdcf6):
    call to ntdll!RtlReAllocateHeap (00000000`775b3f20)
  IPHLPAPI!InternalGetTable+0x93 (000007fe`faabdd13):
    call to ntdll!RtlFreeHeap (00000000`775d3200)
 
so we see this function calls a function pointer which cannot be resolved at the moment. Fair Let's break in there and trace through and notice that we are going to call this function pointer from the stack (rsp is the stack pointer)

IPHLPAPI!InternalGetTable+0x5e (000007fe`faabdcde):
    unresolvable call: call    qword ptr [rsp+78h]

0:000> bp 000007fe`faabdcde
0:000> g
Breakpoint 2 hit
IPHLPAPI!InternalGetTable+0x5e:
000007fe`faabdcde ff542478        call    qword ptr [rsp+78h] ss:00000000`0021fa78={IPHLPAPI!GetTcpTable2 (000007fe`faac13d4)}
0:000> t
IPHLPAPI!GetTcpTable2:
000007fe`faac13d4 4883ec38        sub     rsp,38h
disassembling the Table2 call
0:000> uf /c IPHLPAPI!GetTcpTable2
IPHLPAPI!GetTcpTable2 (000007fe`faac13d4)
  IPHLPAPI!GetTcpTable2+0x15 (000007fe`faac13e9):
    call to IPHLPAPI!GetTcpTableInternal (000007fe`faac104c)
this call then calls the Nsi which is the new way of storing network info since windows 2008/vista onwards
0:000> uf /c IPHLPAPI!GetTcpTableInternal
IPHLPAPI!GetTcpTableInternal (000007fe`faac104c)
  IPHLPAPI!GetTcpTableInternal+0xa8 (000007fe`faac10f4):
    call to IPHLPAPI!NsiAllocateAndGetTable (000007fe`faab1080)
  <<SNIP>>

 So we figure the whole call flow since it;s going to be too much if we keep documenting the steps

 0:000> uf /c NSI!NsiEnumerateObjectsAllParameters
NSI!NsiEnumerateObjectsAllParameters (000007fe`ff381130)
  NSI!NsiEnumerateObjectsAllParameters+0x30 (000007fe`ff381160):
    call to NSI!memset (000007fe`ff381120)
  NSI!NsiEnumerateObjectsAllParameters+0xc4 (000007fe`ff3811f4):
    call to NSI!NsiEnumerateObjectsAllParametersEx (000007fe`ff381224)

0:000> uf /c NSI!NsiEnumerateObjectsAllParametersEx
NSI!NsiEnumerateObjectsAllParametersEx (000007fe`ff381224)
  NSI!NsiEnumerateObjectsAllParametersEx+0x29 (000007fe`ff38124d):
    call to NSI!NsiIoctl (000007fe`ff381010)

0:000> uf /c NSI!NsiIoctl
NSI!NsiIoctl (000007fe`ff381010)
  NSI!NsiIoctl+0xb8 (000007fe`ff381070):
    call to kernel32!CreateEventAStub (00000000`76eb1120)
  NSI!NsiIoctl+0x103 (000007fe`ff3810b4):
    call to ntdll!ZwDeviceIoControlFile (00000000`775d1380)
  NSI!NsiIoctl+0x12c (000007fe`ff3810ca):
    call to kernel32!CloseHandleImplementation (00000000`76ec2f20)
  NSI!NsiIoctl+0x15d (000007fe`ff38147f):
    call to ntdll!RtlNtStatusToDosError (00000000`775d5110)
  NSI!NsiIoctl+0x56 (000007fe`ff3814c1):
    call to kernel32!CreateFileWImplementation (00000000`76eb1870)
  NSI!NsiIoctl+0x181 (000007fe`ff381b0e):
    call to kernel32!DeviceIoControlImplementation (00000000`76eb67c0)
  NSI!NsiIoctl+0x18b (000007fe`ff381b18):
    call to kernel32!GetLastErrorStub (00000000`76ec2d70)
  NSI!NsiIoctl+0x65 (000007fe`ff381cc0):
    call to kernel32!GetLastErrorStub (00000000`76ec2d70)
  NSI!NsiIoctl+0x7c (000007fe`ff381ccb):
    call to kernel32!CloseHandleImplementation (00000000`76ec2f20)
  NSI!NsiIoctl+0xc6 (000007fe`ff381cd7):
    call to kernel32!GetLastErrorStub (00000000`76ec2d70)
  NSI!NsiIoctl+0x11a (000007fe`ff381cea):
    call to ntdll!ZwWaitForSingleObject (00000000`775d1350)

The IPHLPAPI -- > NSI!NsiEnumerateObjectsAllParameters --> NsiEnumerateObjectsAllParametersEx --> NsiIoctl --> ZwDeviceIoControlFile

so we are going to send an IOCTL to the Kernel to get this information. Most probably to NSI kernel interface which will boil to AFD or TCPIP since these are the two components which implement the networking facility in windows. 

 We now need a VM to live debug to understand the call flow or we can simply use process monitor to track this same calls but again, process monitor can be a tricky bet since we can only view stacks where we have a file or registry I/O and IOCTL processing in kernel may or may not have these operations but what the heck!! let's give it a shot  And As I suspected we don't see this either in system process or in netstat process contexts. We do see some RPC calls for lsass and some winsock getnameinfo calls but not this ioctl.

 But this is where we end today since we got to know a great deal of the call flow.
 
 

Thursday, December 8, 2011

The Working of a Semaphore



This can be laughed at but I have always wondered how the limit of semaphore object  is used in windows so I ended up doing a little experiment during my dump analysis routine at work

The signal-state in dispatcher header  is set to the initial count  in this case and this keeps decrementing and once 0 we can’t acquire it any more. This is just a demonstration or a POC for  people who are still learning internals. Initially I thought I will have to set up a live debug scenario to capture this but this was fairly simple using a user mode CDB and livekd.exe. The only glitch in the whole workout is we need to re-launch the livekd every time we need the updated kernel states

This was an exercise I could perform while I was travelling to my office in a cab.  

// Standard code from MSDN demonstrating semaphores
#include <windows.h>
#include <stdio.h>

#define MAX_SEM_COUNT 10
#define THREADCOUNT 12

HANDLE ghSemaphore;

DWORD WINAPI ThreadProc( LPVOID );

void main()
{
    HANDLE aThread[THREADCOUNT];
    DWORD ThreadID;
    int i;

    // Create a semaphore with initial and max counts of MAX_SEM_COUNT

    ghSemaphore = CreateSemaphore(
        NULL,           // default security attributes
        MAX_SEM_COUNT,  // initial count
        MAX_SEM_COUNT,  // maximum count
        NULL);          // unnamed semaphore

    if (ghSemaphore == NULL)
    {
        printf("CreateSemaphore error: %d\n", GetLastError());
        return;
    }

    // Create worker threads

    for( i=0; i < THREADCOUNT; i++ )
    {
        aThread[i] = CreateThread(
                     NULL,       // default security attributes
                     0,          // default stack size
                     (LPTHREAD_START_ROUTINE) ThreadProc,
                     NULL,       // no thread function arguments
                     0,          // default creation flags
                     &ThreadID); // receive thread identifier

        if( aThread[i] == NULL )
        {
            printf("CreateThread error: %d\n", GetLastError());
            return;
        }
    }

    // Wait for all threads to terminate

    WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);

    // Close thread and semaphore handles

    for( i=0; i < THREADCOUNT; i++ )
        CloseHandle(aThread[i]);

    CloseHandle(ghSemaphore);
}

DWORD WINAPI ThreadProc( LPVOID lpParam )
{
    DWORD dwWaitResult;
    BOOL bContinue=TRUE;

    while(bContinue)
    {
        // Try to enter the semaphore gate.

        dwWaitResult = WaitForSingleObject(
            ghSemaphore,   // handle to semaphore
            0L);           // zero-second time-out interval

        switch (dwWaitResult)
        {
            // The semaphore object was signaled.
            case WAIT_OBJECT_0:
                // TODO: Perform task
                printf("Thread %d: wait succeeded\n", GetCurrentThreadId());
                bContinue=FALSE;           

                // Simulate thread spending time on task
                Sleep(5*1000*60);

                // Relase the semaphore when task is finished

                if (!ReleaseSemaphore(
                        ghSemaphore,  // handle to semaphore
                        1,            // increase count by one
                        NULL) )       // not interested in previous count
                {
                    printf("ReleaseSemaphore error: %d\n", GetLastError());
                }
                break;

            // The semaphore was nonsignaled, so a time-out occurred.
            case WAIT_TIMEOUT:
                printf("Thread %d: wait timed out\n", GetCurrentThreadId());
                break;
        }
    }
    return TRUE;
}


/*

DEBUGGER OUTPUTS

User mode CDB

D:\addy\src>c:\debug86\cdb semaphore.exe

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: semaphore.exe
Symbol search path is: srv*d:\symbols\public*http://msdl.microsoft.com/download/symbols;srv*d:\symbols\citrix*http://
Executable search path is:
ModLoad: 00310000 0031f000   image00310000
ModLoad: 77090000 771cd000   ntdll.dll
ModLoad: 75930000 75a04000   C:\Windows\system32\kernel32.dll
ModLoad: 753c0000 7540a000   C:\Windows\system32\KERNELBASE.dll
(21e8.4f4): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=0041f3a0 edx=770d6344 esi=fffffffe edi=00000000
eip=7712ebbe esp=0041f3bc ebp=0041f3e8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!LdrpDoDebuggerBreak+0x2c:
7712ebbe cc              int     3
0:000> bp kernel32!CreateSemaphoreA
0:000> bp kernel32!CreateSemaphoreW
0:000> g
Breakpoint 0 hit
eax=005c2150 ebx=7ffdf000 ecx=00000001 edx=770d6344 esi=00000000 edi=00000000
eip=7596bdd7 esp=0041f788 ebp=0041f7d4 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
kernel32!CreateSemaphoreA:
7596bdd7 8bff            mov     edi,edi
0:000> kvn
*** WARNING: Unable to verify checksum for image00310000
*** ERROR: Module load completed but symbols could not be loaded for image00310000
# ChildEBP RetAddr  Args to Child
00 0041f784 00311014 00000000 0000000a 0000000a kernel32!CreateSemaphoreA (FPO: [Non-Fpo])
WARNING: Stack unwind information not available. Following frames may be wrong.
01 0041f7d4 00311385 00000001 005c2120 005c2150 image00310000+0x1014
02 0041f81c 75981114 7ffdf000 0041f868 770eb429 image00310000+0x1385
03 0041f828 770eb429 7ffdf000 731c916d 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
04 0041f868 770eb3fc 003113db 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
05 0041f880 00000000 003113db 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
0:000> gu
eax=00000020 ebx=7ffdf000 ecx=7ffde000 edx=00000000 esi=00000000 edi=00000000
eip=00311014 esp=0041f79c ebp=0041f7d4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
image00310000+0x1014:
00311014 a3dcca3100      mov     dword ptr [image00310000+0xcadc (0031cadc)],eax ds:0023:0031cadc=00000000
0:000> g
 0:000>** Eax has the return value from the CreateSemaphore which is the handle this value can be used to
 0:000>**  get the object once we change the process context in the livekd launched debugger in this case kd

Live KD
Creation of Semaphore object
0: kd> .process -r -p 89594030
Implicit process is now 89594030
Loading User Symbols
....
0: kd> !handle 20

PROCESS 89594030  SessionId: 1  Cid: 21e8    Peb: 7ffdf000  ParentCid
    DirBase: d98bbfc0  ObjectTable: ba811088  HandleCount:   8.
    Image: semaphore.exe

Handle table at ec021000 with 8 entries in use

0020: Object: 89aba490  GrantedAccess: 001f0003 Entry: ec021040
Object: 89aba490  Type: (85ed1518) Semaphore
    ObjectHeader: 89aba478 (new version)
        HandleCount: 1  PointerCount: 1


0: kd> dt nt!_KSEMAPHORE 89aba490 รง init via KeInitializeSemaphore
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 Limit            : 0n10 <===
0: kd> dt nt!_KSEMAPHORE 89aba490 Header.
   +0x000 Header  :
      +0x000 Type    : 0x5 ''
      +0x001 TimerControlFlags : 0 ''
      +0x001 Absolute : 0y0
      +0x001 Coalescable : 0y0
      +0x001 KeepShifting : 0y0
      +0x001 EncodedTolerableDelay : 0y00000 (0)
      +0x001 Abandoned : 0 ''
      +0x001 Signalling : 0 ''
      +0x002 ThreadControlFlags : 0x5 ''
      +0x002 CpuThrottled : 0y1
      +0x002 CycleProfiling : 0y0
      +0x002 CounterProfiling : 0y1
      +0x002 Reserved : 0y00000 (0)
      +0x002 Hand    : 0x5 ''
      +0x002 Size    : 0x5 ''
      +0x003 TimerMiscFlags : 0 ''
      +0x003 Index   : 0y0
      +0x003 Processor : 0y00000 (0)
      +0x003 Inserted : 0y0
      +0x003 Expired : 0y0
      +0x003 DebugActive : 0 ''
      +0x003 ActiveDR7 : 0y0
      +0x003 Instrumented : 0y0
      +0x003 Reserved2 : 0y0000
      +0x003 UmsScheduled : 0y0
      +0x003 UmsPrimary : 0y0
      +0x003 DpcActive : 0 ''
      +0x000 Lock    : 0n327685
      +0x004 SignalState : 0n10 <<====
      +0x008 WaitListHead : _LIST_ENTRY [ 0x89aba498 - 0x89aba498 ]


After acquisitions
----------------------
0: kd> .process -r -p 89594030
Implicit process is now 89594030
Loading User Symbols
....
0: kd> !handle 20

PROCESS 89594030  SessionId: 1  Cid: 21e8    Peb: 7ffdf000  ParentCid: 0f3c
    DirBase: d98bbfc0  ObjectTable: ba811088  HandleCount:  22.
    Image: semaphore.exe

Handle table at ec021000 with 22 entries in use

0020: Object: 89aba490  GrantedAccess: 001f0003 Entry: ec021040
Object: 89aba490  Type: (85ed1518) Semaphore
    ObjectHeader: 89aba478 (new version)
        HandleCount: 1  PointerCount: 2


0: kd> dt nt!_KSEMAPHORE 89aba490
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 Limit            : 0n10
0: kd> dt nt!_KSEMAPHORE 89aba490 Header.
   +0x000 Header  :
      +0x000 Type    : 0x5 ''
      +0x001 TimerControlFlags : 0 ''
      +0x001 Absolute : 0y0
      +0x001 Coalescable : 0y0
      +0x001 KeepShifting : 0y0
      +0x001 EncodedTolerableDelay : 0y00000 (0)
      +0x001 Abandoned : 0 ''
      +0x001 Signalling : 0 ''
      +0x002 ThreadControlFlags : 0x5 ''
      +0x002 CpuThrottled : 0y1
      +0x002 CycleProfiling : 0y0
      +0x002 CounterProfiling : 0y1
      +0x002 Reserved : 0y00000 (0)
      +0x002 Hand    : 0x5 ''
      +0x002 Size    : 0x5 ''
      +0x003 TimerMiscFlags : 0 ''
      +0x003 Index   : 0y0
      +0x003 Processor : 0y00000 (0)
      +0x003 Inserted : 0y0
      +0x003 Expired : 0y0
      +0x003 DebugActive : 0 ''
      +0x003 ActiveDR7 : 0y0
      +0x003 Instrumented : 0y0
      +0x003 Reserved2 : 0y0000
      +0x003 UmsScheduled : 0y0
      +0x003 UmsPrimary : 0y0
      +0x003 DpcActive : 0 ''
      +0x000 Lock    : 0n327685
      +0x004 SignalState : 0n0 รง Queue Full can’t acquire anymore
      +0x008 WaitListHead : _LIST_ENTRY [ 0x89aba498 - 0x89aba498 ]


Tracking each acquisition

eax=00000020 ebx=00000000 ecx=00000000 edx=00151005 esi=00000000 edi=00000000
eip=7597ef83 esp=0076ff04 ebp=0076ff04 iopl=0         nv up ei pl nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
kernel32!WaitForSingleObjectExImplementation+0x48:
7597ef83 8bc8            mov     ecx,eax
0:001> gu
eax=00000000 ebx=00000000 ecx=753c17c4 edx=770d6344 esi=00000000 edi=00000000
eip=7597ef52 esp=0076ff18 ebp=0076ff18 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
kernel32!WaitForSingleObject+0x12:
7597ef52 5d              pop     ebp
0:001> t
Breakpoint 0 hit
eax=75981102 ebx=00000000 ecx=00000000 edx=00151005 esi=00000000 edi=00000000
eip=00151100 esp=00c0f988 ebp=00c0f990 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
semaphore!ThreadProc:
00151100 55              push    ebp
0:002>
eax=75981102 ebx=00000000 ecx=00000000 edx=00151005 esi=00000000 edi=00000000
eip=00151101 esp=00c0f984 ebp=00c0f990 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
semaphore!ThreadProc+0x1:
00151101 8bec            mov     ebp,esp
0:002>
eax=75981102 ebx=00000000 ecx=00000000 edx=00151005 esi=00000000 edi=00000000
eip=00151103 esp=00c0f984 ebp=00c0f984 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
semaphore!ThreadProc+0x3:
00151103 83ec0c          sub     esp,0Ch
0:002> kvn
# ChildEBP RetAddr  Args to Child
00 00c0f984 75981114 00000000 00c0f9d0 770eb429 semaphore!ThreadProc+0x3 (FPO: [Non-Fpo]) (CONV: std
01 00c0f990 770eb429 00000000 738241d2 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
02 00c0f9d0 770eb3fc 00151005 00000000 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
03 00c0f9e8 00000000 00151005 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])


0: kd> dt nt!_KSEMAPHORE 86acba70

*** ERROR: Module load completed but symbols could not be loaded for LiveKdD.SYS
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 Limit            : 0n10
0: kd>    +0x000 Header           : _DISPATCHER_HEADER
   +0x010 Limit            : 0n10
0: kd> dt nt!_KSEMAPHORE 86acba70 Header.
   +0x000 Header  :
      +0x000 Type    : 0x5 ''
      +0x001 TimerControlFlags : 0 ''
      +0x001 Absolute : 0y0
      +0x001 Coalescable : 0y0
      +0x001 KeepShifting : 0y0
      +0x001 EncodedTolerableDelay : 0y00000 (0)
      +0x001 Abandoned : 0 ''
      +0x001 Signalling : 0 ''
      +0x002 ThreadControlFlags : 0x5 ''
      +0x002 CpuThrottled : 0y1
      +0x002 CycleProfiling : 0y0
      +0x002 CounterProfiling : 0y1
      +0x002 Reserved : 0y00000 (0)
      +0x002 Hand    : 0x5 ''
      +0x002 Size    : 0x5 ''
      +0x003 TimerMiscFlags : 0 ''
      +0x003 Index   : 0y0
      +0x003 Processor : 0y00000 (0)
      +0x003 Inserted : 0y0
      +0x003 Expired : 0y0
      +0x003 DebugActive : 0 ''
      +0x003 ActiveDR7 : 0y0
      +0x003 Instrumented : 0y0
      +0x003 Reserved2 : 0y0000
      +0x003 UmsScheduled : 0y0
      +0x003 UmsPrimary : 0y0
      +0x003 DpcActive : 0 ''
      +0x000 Lock    : 0n327685
      +0x004 SignalState : 0n9
      +0x008 WaitListHead : _LIST_ENTRY [ 0x86acba78 - 0x86acba78 ]

2 more acquires

0:003>
eax=00000020 ebx=00000000 ecx=00000000 edx=00151005 esi=00000000 edi=00000000
eip=7597ef40 esp=0060f8c8 ebp=0060f8e0 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!WaitForSingleObject:
7597ef40 8bff            mov     edi,edi
0:003>
eax=00000020 ebx=00000000 ecx=00000000 edx=00151005 esi=00000000 edi=00000000
eip=7597ef42 esp=0060f8c8 ebp=0060f8e0 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!WaitForSingleObject+0x2:
7597ef42 55              push    ebp
0:003> gu
eax=00000000 ebx=00000000 ecx=753c17c4 edx=770d6344 esi=00000000 edi=00000000
eip=00151125 esp=0060f8d4 ebp=0060f8e0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
semaphore!ThreadProc+0x25:
00151125 8945fc          mov     dword ptr [ebp-4],eax ss:0023:0060f8dc=00000000
0:003> t
eax=00000000 ebx=00000000 ecx=753c17c4 edx=770d6344 esi=00000000 edi=00000000
eip=00151128 esp=0060f8d4 ebp=0060f8e0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
semaphore!ThreadProc+0x28:
00151128 8b4dfc          mov     ecx,dword ptr [ebp-4] ss:0023:0060f8dc=00000000
0:003>
eax=00000000 ebx=00000000 ecx=00000000 edx=770d6344 esi=00000000 edi=00000000
eip=0015112b esp=0060f8d4 ebp=0060f8e0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
semaphore!ThreadProc+0x2b:


0: kd> dt nt!_KSEMAPHORE 86acba70
*** ERROR: Module load completed but symbols could not be loaded for LiveKdD.SYS
   +0x000 Header           : _DISPATCHER_HEADER
   +0x010 Limit            : 0n10
0: kd> dt nt!_KSEMAPHORE 86acba70 Header.
   +0x000 Header  :
      +0x000 Type    : 0x5 ''
      +0x001 TimerControlFlags : 0 ''
      +0x001 Absolute : 0y0
      +0x001 Coalescable : 0y0
      +0x001 KeepShifting : 0y0
      +0x001 EncodedTolerableDelay : 0y00000 (0)
      +0x001 Abandoned : 0 ''
      +0x001 Signalling : 0 ''
      +0x002 ThreadControlFlags : 0x5 ''
      +0x002 CpuThrottled : 0y1
      +0x002 CycleProfiling : 0y0
      +0x002 CounterProfiling : 0y1
      +0x002 Reserved : 0y00000 (0)
      +0x002 Hand    : 0x5 ''
      +0x002 Size    : 0x5 ''
      +0x003 TimerMiscFlags : 0 ''
      +0x003 Index   : 0y0
      +0x003 Processor : 0y00000 (0)
      +0x003 Inserted : 0y0
      +0x003 Expired : 0y0
      +0x003 DebugActive : 0 ''
      +0x003 ActiveDR7 : 0y0
      +0x003 Instrumented : 0y0
      +0x003 Reserved2 : 0y0000
      +0x003 UmsScheduled : 0y0
      +0x003 UmsPrimary : 0y0
      +0x003 DpcActive : 0 ''
      +0x000 Lock    : 0n327685
      +0x004 SignalState : 0n7
      +0x008 WaitListHead : _LIST_ENTRY [ 0x86acba78 - 0x86acba78 ]

      .      .       .      .    .. .     
and so on till signal state becomes 0



*/