⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objexp.bat

📁 用汇编语言编写Windows驱动程序的工具
💻 BAT
📖 第 1 页 / 共 5 页
字号:
					.break
				.endif
				add ebx, sizeof LPWSTR	; next type name
				.break .if ebx > g_cbObjectTypeNames		; break if end of array
			.endw

			; Get selected list view item (object name)
			mov [esi].imask, LVIF_PARAM
			m2m [esi].iItem, iSelectedItem
			and [esi].iSubItem, 0
			ListView_GetItem g_hwndListView, esi
			mov eax, [esi].lParam
			assume esi:nothing
		.else
			xor eax, eax
		.endif
	.else
		; Get selected tree view item (directory path)
		lea esi, tvi
		assume esi:ptr TV_ITEM
		mov [esi]._mask, TVIF_PARAM
		TreeView_GetSelection g_hwndTreeView		; our tree view has always something selected, but...
		mov [esi].hItem, eax
		; Each tree view item contains associated string with directory path in lParam
		TreeView_GetItem g_hwndTreeView, esi
		mov eax, [esi].lParam
		mov ebx, IMG_ID_DIRECTORY
		assume edi:nothing
	.endif

	; eax -> object path (unicode) or NULL
	; ecx = object type
	.if eax != NULL
		invoke OpenObject, eax, ebx
	.endif

	ret

OpenSelectedObject endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                  GetSelectedObjectTypeIndex                                       
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

GetSelectedObjectTypeIndex proc uses esi ebx

; Returns object type index or -1 on errors

local tvi:TV_ITEM
local lvi:LV_ITEM
local buffer[256]:CHAR

	invoke GetFocus
	.if eax == g_hwndListView
		lea esi, lvi
		assume esi:ptr LV_ITEM
		; Get object type
		mov [esi].imask, LVIF_TEXT
		ListView_GetNextItem g_hwndListView, -1, LVNI_SELECTED
		.if eax != -1
			mov [esi].iItem, eax
			mov [esi].iSubItem, 1
			lea eax, buffer
			mov [esi].pszText, eax
			mov [esi].cchTextMax, sizeof buffer
			invoke SendMessage, g_hwndListView, LVM_GETITEMW, 0, esi

			xor ebx, ebx			; undex
			.while TRUE
				; Which type ?
;				invoke wcscmp, addr buffer, g_apuszObjectTypeNames[ebx]
				invoke _wcsicmp, addr buffer, g_apuszObjectTypeNames[ebx]
				.if eax == 0
					shr ebx, 2				; / sizeof LPWSTR = object type index
					.break
				.endif
				add ebx, sizeof LPWSTR	; next type name
				.break .if ebx > g_cbObjectTypeNames		; break if end of array
			.endw

		.else
			xor eax, eax
		.endif
	.elseif eax == g_hwndTreeView
		mov ebx, IMG_ID_DIRECTORY
	.endif

	mov eax, ebx
	ret

GetSelectedObjectTypeIndex endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                     ShowObjectProperties                                          
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

ShowObjectProperties proc uses esi edi

local hObject:HANDLE
local psp:PROPSHEETPAGE
local psh:PROPSHEETHEADER
;local obi:OBJECT_BASIC_INFORMATION
local dwLenghtReturned:DWORD

local oi:OBJECT_INFORMATION
local poni:POBJECT_NAME_INFORMATION
local poti:POBJECT_TYPE_INFORMATION 

	invoke OpenSelectedObject
	.if eax != NULL
		mov hObject, eax

		lea esi, oi
		assume esi:ptr OBJECT_INFORMATION
		invoke ZwQueryObject, hObject, ObjectBasicInformation, addr [esi].BasicInformation, sizeof OBJECT_BASIC_INFORMATION, addr dwLenghtReturned
		.if eax == STATUS_SUCCESS

			dec [esi].BasicInformation.HandleCount			; correct count of handles
			dec [esi].BasicInformation.PointerCount			; the ref count is also one more

Fix Add error checking

			invoke malloc, 1000h
			mov poni, eax
			invoke ZwQueryObject, hObject, ObjectNameInformation, poni, 1000h, addr dwLenghtReturned

			; If object is file QueryDirectoryObject tells that it's 'Device'
			; but ZwQueryObject,, ObjectTypeInformation, tells that it's 'File'
			invoke malloc, 1000h
			mov poti, eax
			invoke ZwQueryObject, hObject, ObjectTypeInformation, poti, 1000h, addr dwLenghtReturned

			invoke ZwClose, hObject
			and hObject, NULL

			invoke memcpy, addr [esi]._Name, poni, sizeof UNICODE_STRING
			invoke memcpy, addr [esi].TypeName, poti, sizeof UNICODE_STRING

			invoke GetSelectedObjectTypeIndex
			mov [esi].ObjectTypeIndex, eax

			lea edi, psp
			assume edi:ptr PROPSHEETPAGE
			mov [edi].dwSize, sizeof PROPSHEETPAGE
			mov [edi].dwFlags, PSP_USEICONID + PSP_USETITLE
			m2m [edi].hInstance, g_hInstance
			mov [edi].pszTemplate, IDD_PROPERTIES
			and [edi].pszIcon, NULL
			mov [edi].pfnDlgProc, offset PropertyDialogProc
			mov [edi].pszTitle, $CTA0("Object Info")
			mov [edi].lParam, esi
			and [edi].pfnCallback, NULL

			lea edi, psh
			assume edi:ptr PROPSHEETHEADER
			mov [edi].dwSize, sizeof PROPSHEETHEADER
			mov [edi].dwFlags, PSH_USEICONID + PSH_PROPSHEETPAGE
			m2m [edi].hwndParent, g_hWnd
			m2m [edi].hInstance, g_hInstance
			and [edi].pszIcon, NULL
			mov [edi].pszCaption, $CTA0("Properties")
			mov [edi].nPages, 1					; sizeof psp / sizeof PROPSHEETPAGE
			and [edi].nStartPage, 0
			lea eax, psp
			mov [edi].ppsp, eax
			and [edi].pfnCallback, NULL
			assume edi:nothing
			invoke PropertySheet, edi

			invoke free, poni
			invoke free, poti

		.else
			invoke GetFocus
			push eax
			invoke MessageBox, g_hWnd, $CTA0("Couldn't query object info."), NULL, MB_ICONERROR
			call SetFocus
		.endif
		assume esi:nothing
		.if hObject != NULL
			invoke ZwClose, hObject
		.endif
	.endif

	ret

ShowObjectProperties endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                    QueryDirectoryObject                                           
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

QueryDirectoryObject proc uses esi ebx puszDirectoryPath:LPWSTR

; Returns - pointer to array of DIRECTORY_BASIC_INFORMATION
;           NULL if unsuccesseful

local status:NTSTATUS
local oa:OBJECT_ATTRIBUTES
local us:UNICODE_STRING
local hDirectory:HANDLE

;local cb:UINT
local dwLenghtReturned:DWORD
local Context:LPVOID

	xor esi, esi			; assume unsuccess

	invoke RtlInitUnicodeString, addr us, puszDirectoryPath
	lea ecx, oa
	lea edx, us
	InitializeObjectAttributes ecx, edx, OBJ_CASE_INSENSITIVE, NULL, NULL
	invoke ZwOpenDirectoryObject, addr hDirectory, DIRECTORY_QUERY, addr oa
	.if eax == STATUS_SUCCESS

		mov ebx, 800h
		.while TRUE
			invoke malloc, ebx
			.break .if eax == NULL
			mov esi, eax
			invoke ZwQueryDirectoryObject, hDirectory, esi, ebx, FALSE, TRUE, addr Context, addr dwLenghtReturned
			.if eax == STATUS_SUCCESS
				.break
			.elseif ( eax == STATUS_NO_MORE_ENTRIES ) || ( eax == STATUS_ACCESS_DENIED )
				; directory is empty or access denied
				invoke free, esi
				xor esi, esi
				.break
			.elseif ( eax == STATUS_MORE_ENTRIES ) || ( eax == STATUS_BUFFER_TOO_SMALL )
				invoke free, esi		; Try again
				xor esi, esi
				shl ebx, 1				; Ask twice more memory
				.if ebx > 1000h * 100	; 400k
					.break				; We need to big buffer -> something went wrong
										; Better go away from here
				.endif
			.else

			.endif
		.endw
		invoke ZwClose, hDirectory
	.endif

	mov eax, esi
	ret

QueryDirectoryObject endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                    QuerySymbolicLinkObject                                        
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

QuerySymbolicLinkObject proc uses esi ebx puszSymbolicLinkPath:LPWSTR

; Allocates memory from process heap
; Retrieves name of the object symbolic link links to
; Stores retrieved UNICODE_STRING and name into allocated memory

; Returns - pointer to UNICODE_STRING
;           NULL if unsuccesseful

local status:NTSTATUS
local oa:OBJECT_ATTRIBUTES
local us:UNICODE_STRING
local hSymbolicLink:HANDLE

;local cb:UINT
local dwLenghtReturned:DWORD
local Context:LPVOID

	xor esi, esi			; assume unsuccess

	invoke RtlInitUnicodeString, addr us, puszSymbolicLinkPath
	lea ecx, oa
	lea edx, us
	InitializeObjectAttributes ecx, edx, OBJ_CASE_INSENSITIVE, NULL, NULL
	invoke ZwOpenSymbolicLinkObject, addr hSymbolicLink, SYMBOLIC_LINK_QUERY, addr oa
	.if eax == STATUS_SUCCESS

		mov ebx, 800h
		.while TRUE
			invoke malloc, ebx
			.break .if eax == NULL
			mov esi, eax
			assume esi:ptr UNICODE_STRING
			and [esi]._Length, 0
			mov eax, ebx
			sub eax, sizeof UNICODE_STRING
			mov [esi].MaximumLength, ax
			lea eax, [esi][sizeof UNICODE_STRING]
			mov [esi].Buffer, eax
			assume esi:nothing
			invoke ZwQuerySymbolicLinkObject, hSymbolicLink, esi, addr dwLenghtReturned
			.if eax == STATUS_SUCCESS
				.break
			.elseif eax == STATUS_ACCESS_DENIED
				; directory is empty or access denied
				invoke free, esi
				xor esi, esi
				.break
			.elseif ( eax == STATUS_BUFFER_TOO_SMALL )
				invoke free, esi		; Try again
				xor esi, esi
				shl ebx, 1				; Ask twice more memory
				.if ebx > 1000h * 10	; 40k is enough for symbolic link object
					.break				; We need to big buffer -> something went wrong
										; Better go away from here
				.endif
			.else

			.endif
		.endw
		invoke ZwClose, hSymbolicLink
	.endif

	mov eax, esi
	ret

QuerySymbolicLinkObject endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                         MakeFullPath                                              
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

MakeFullPath proc uses esi edi puszDirectoryPath:LPWSTR, pusObjectName:PTR UNICODE_STRING

; Makes full path to object from directory path and object name
; Allocates buffer from process heap and stores created full path into it
; Returns pointer to allocated memory with full path or NULL if unsuccessful

	invoke wcslen, puszDirectoryPath
	shl eax, 1									; * sizeof WCHAR = len in bytes (not including terminated zero)

	mov esi, pusObjectName
	add ax, (UNICODE_STRING PTR [esi])._Length	; + srtlen(ObjectName). Hope len of path never grows above FFFFh
	add eax, 4									; take into account separating '\' and terminating zero

	invoke malloc, eax
	.if eax != NULL
		mov edi, eax
		invoke wcscpy, edi, puszDirectoryPath

		invoke wcscmp, puszDirectoryPath, offset g_uszBackSlash
		; If it not the root directory add backslash
		.if eax
			invoke wcscat, edi, offset g_uszBackSlash
		.endif
		invoke wcscat, edi, (UNICODE_STRING PTR [esi]).Buffer
	.else
		xor edi, edi
	.endif

	mov eax, edi
	ret

MakeFullPath endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                     FillTreeViewNode                                              
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

FillTreeViewNode proc uses esi edi ebx hTvUpperNode:HTREEITEM, puszDirectoryPath:LPWSTR

local status:NTSTATUS
local oa:OBJECT_ATTRIBUTES
local us:UNICODE_STRING
local hDirectory:HANDLE
;local pdbi:PDIRECTORY_BASIC_INFORMATION
local cb:UINT
local dwLenghtReturned:DWORD
local Context:LPVOID

local tvins:TV_INSERTSTRUCTW
local hTvNode:HTREEITEM

	invoke QueryDirectoryObject, puszDirectoryPath

	.if eax != NULL
		mov esi, eax			; -> array of DIRECTORY_BASIC_INFORMATION

		push esi				; save for invoke free, esi
		assume esi:ptr DIRECTORY_BASIC_INFORMATION

		; Create TreeView Node
		lea edi, tvins
		assume edi:ptr TV_INSERTSTRUCTW
		mrm [edi].hParent, hTvUpperNode
		mov [edi].hInsertAfter, TVI_LAST
		mov [edi].item._mask, TVIF_TEXT + TVIF_SELECTEDIMAGE + TVIF_IMAGE + TVIF_PARAM
		mov [edi].item.iImage, IMG_ID_DIRECTORY
		mov [edi].item.iSelectedImage, IMG_ID_DIRECTORY_OPN

		; The array is terminated with zeroed DIRECTORY_BASIC_INFORMATION structure
		; But we check only first two dwords. It's enough.
		.while (dword ptr [esi] != 0) && (dword ptr [esi][4] != 0)
			mov eax, [esi].ObjectTypeName.Buffer

;			invoke wcscmp, eax, $CTW0("Directory")
			invoke _wcsicmp, eax, $CTW0("Directory")
			; Only objects of type "Directory" is of interest for us
			.if eax == 0

				; Make full path to object and associate it with tree view item
				; Later we have manually free this memory
				invoke MakeFullPath, puszDirectoryPath, addr [esi].ObjectName
				mov [edi].item.lParam, eax
				mrm [edi].item.pszText, [esi].ObjectName.Buffer
				;TreeView_InsertItem g_hwndTreeView, edi
				invoke SendMessage, g_hwndTreeView, TVM_INSERTITEMW, 0, edi
				; If current directory contains other directories fill it recursivelly
				invoke FillTreeViewNode, eax, [edi].item.lParam

			.endif

			add esi, sizeof DIRECTORY_BASIC_INFORMATION
		.endw
		assume edi:nothing
		pop esi
		invoke free, esi
		assume esi:nothing
	.endif

	ret

FillTreeViewNode endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                      DeleteListView                                               
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DeleteListView proc uses esi ebx

; Frees all memory associated with each list view item and deletes all items

local lvi:LV_ITEM

	ListView_GetItemCount g_hwndListView
	.if eax != 0
		mov ebx, eax

		lea esi, lvi
		assume esi:ptr LV_ITEM
		mov lvi.imask, LVIF_PARAM

		.while ebx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -