Rebuilded CloseHandle Api
I never imagined that it was so close to TEB instructions.
Proc CloseHandle::
Arguments @hObject
Local @ProcessParams
Uses ecx, edx, esi, ebx
call GetProcessParametersFromTEB &NULL
mov esi eax
If D@hObject = &STD_ERROR_HANDLE
mov eax D$esi+RTL_USER_PROCESS_PARAMETERS.StandardErrorDis
Else_If D@hObject = &STD_OUTPUT_HANDLE
mov eax D$esi+RTL_USER_PROCESS_PARAMETERS.StandardOutputDis
Else_If D@hObject = &STD_INPUT_HANDLE
mov eax D$esi+RTL_USER_PROCESS_PARAMETERS.StandardInputDis
Else
mov eax D@hObject
End_If
mov ecx eax
and ecx &HANDLE_ULONG__&CONSOLE_HANDLE_SIGNATURE
...If ecx = &CONSOLE_HANDLE_SIGNATURE
call 'kernel32.CloseConsoleHandle' eax
...Else
call 'ntdll.NtClose' eax
If eax <> &STATUS_SUCCESS
call BaseSetLastNTError eax
xor eax eax
Else
mov eax &TRUE
End_If
...End_if
EndP
; eax will return the pointer to RTL_USER_PROCESS_PARAMETERS structure and also store it on the buffer if poutput is not null
Proc GetProcessParametersFromTEB:
Arguments @pOutput
Uses edi
mov edi D@pOutput
mov eax D$fs:TEB.Tib.SelfDis ; retrieve TEB structure for the current process
mov eax D$eax+TEB.PebDis ; pointer to a PEB structure
mov eax D$eax+PEB.ProcessParametersDis ; retrieve the pointer to RTL_USER_PROCESS_PARAMETERS structure
If edi <> 0 ; saveit to a buffer, if it is not null
mov D$edi eax
End_If
EndP
Proc BaseSetLastNTError:
Arguments @ErrorCode
Uses esi, ecx, edx, ebx
call 'ntdll.RtlNtStatusToDosError' D@ErrorCode | mov esi eax
call 'kernel32.SetLastError' eax
mov eax esi
EndP
And for thjose who would like to take a look at "another mess" that M$ made, here is CloseConsoleHandle
CloseConsoleHandle internally should allocate only a few bytes, but it makes some mess on the local stack while trying to allocate enough data to the structure CSR_API_MSG (Which was a hell to identify inside the sources.)
[CSR_API_MSG.h.u1.LengthDis 0
CSR_API_MSG.h.u2.ZeroInitDis 4
CSR_API_MSG.h.cid.UniqueProcessDis 8
CSR_API_MSG.h.cid.UniqueThreadDis 12
CSR_API_MSG.h.MessageIdDis 16
CSR_API_MSG.h.ClientViewSizeDis 20
CSR_API_MSG.CaptureBufferDis 24
CSR_API_MSG.ApiNumberDis 28
CSR_API_MSG.ReturnValueDis 32
CSR_API_MSG.ReservedDis 36
CSR_API_MSG.CloseHandle.ConsoleHandleDis 40
CSR_API_MSG.CloseHandle.HandleDis 44
CSR_API_MSG.ApiMessageDataDis 48]
[Size_Of_CSR_API_MSG 160]
[CONSOLE_CLOSEHANDLE_MSG.ConsoleHandleDis 0
CONSOLE_CLOSEHANDLE_MSG.HandleDis 4]
[Size_Of_CONSOLE_CLOSEHANDLE_MSG 8]
[CSR_MAKE_API_NUMBER | ((#1 shl 16) or (#2))]
Proc CloseConsoleHandle::
Arguments @hConsole
Structure @CSR_API_MSG 160, @CSR_API_MSG.h.u1.LengthDis 0, @CSR_API_MSG.h.u2.ZeroInitDis 4, @CSR_API_MSG.h.cid.UniqueProcessDis 8,
@CSR_API_MSG.h.cid.UniqueThreadDis 12, @CSR_API_MSG.h.MessageIdDis 16, @CSR_API_MSG.h.ClientViewSizeDis 20,
@CSR_API_MSG.CaptureBufferDis 24, @CSR_API_MSG.ApiNumberDis 28, @CSR_API_MSG.ReturnValueDis 32,
@CSR_API_MSG.ReservedDis 36, @CSR_API_MSG.CloseHandle.ConsoleHandleDis 40, @CSR_API_MSG.CloseHandle.HandleDis 44,
@CSR_API_MSG.ApiMessageDataDis 48
Uses ecx, esi, edi, ebx, edx
; damn M$ This function is buggy inside kernel. The size of the structure is wrong
; The amount of data of the structure size is due to a alignment of their members, since it
; contains unions of structures with different sizes. A true mess
; inside stream.c (from nt source) it is a macro called GET_CONSOLE_HANDLE
call FastZeroMem D@CSR_API_MSG, Size_Of_CSR_API_MSG
mov D@CSR_API_MSG.h.u1.LengthDis Size_Of_CSR_API_MSG
call GetProcessParametersFromTEB &NULL
mov esi eax
move D@CSR_API_MSG.CloseHandle.ConsoleHandleDis D$esi+RTL_USER_PROCESS_PARAMETERS.ConsoleHandleDis
move D@CSR_API_MSG.CloseHandle.HandleDis D@hConsole
call 'ntdll.CsrClientCallServer' D@CSR_API_MSG, &NULL, {CSR_MAKE_API_NUMBER &CONSRV_SERVERDLL_INDEX, 546}, Size_Of_CONSOLE_CLOSEHANDLE_MSG; 020222, Size_Of_CONSOLE_CLOSEHANDLE_MSG
;mov eax (020222 shr 16)
;mov eax {CSR_MAKE_API_NUMBER &CONSRV_SERVERDLL_INDEX, 546}
If D@CSR_API_MSG.ReturnValueDis = &STATUS_SUCCESS
mov eax &TRUE
Else
call BaseSetLastNTError D@CSR_API_MSG.ReturnValueDis
xor eax eax
End_If
EndP
Btw...CsrClientCallServer uses a table to handle the console and perhaps other communication devices. Thefunction i rebuild i have no idea if it works on others Win versions, since on mine, the 3rd argument of this function have a value of 020222. Achieved from the macro {CSR_MAKE_API_NUMBER &CONSRV_SERVERDLL_INDEX, 546}
The value 546 is just an index. In fact it must be subtracted by 512 to retrieve the values of ConsolepCloseHandle, ConsolepCreateScreenBuffer etc. Since i didn´t built the proper equates for them, i simply let it as the full value shifted left by 16 and 'Or'ing to 2 (&CONSRV_SERVERDLL_INDEX) as the original source code.
NOte: The enumeratedtable is as follows:
CONSRV_FIRST_API_NUMBER = 512
csr name crs enumerated value csr index
ConsolepOpenConsole 512 0
ConsolepGetConsoleInput, 513 1
ConsolepWriteConsoleInput, 514 2
ConsolepReadConsoleOutput, 515 3
ConsolepWriteConsoleOutput, 516 4
ConsolepReadConsoleOutputString, 517 5
ConsolepWriteConsoleOutputString, 518 6
ConsolepFillConsoleOutput, 519 7
ConsolepGetMode, 520 8
ConsolepGetNumberOfFonts, 521 9
ConsolepGetNumberOfInputEvents, 522 10
ConsolepGetScreenBufferInfo, 523 11
ConsolepGetCursorInfo, 524 12
ConsolepGetMouseInfo, 525 13
ConsolepGetFontInfo, 526 14
ConsolepGetFontSize, 527 15
ConsolepGetCurrentFont, 528 16
ConsolepSetMode, 529 17
ConsolepSetActiveScreenBuffer, 530 18
ConsolepFlushInputBuffer, 531 19
ConsolepGetLargestWindowSize, 532 20
ConsolepSetScreenBufferSize, 533 21
ConsolepSetCursorPosition, 534 22
ConsolepSetCursorInfo, 535 23
ConsolepSetWindowInfo, 536 24
ConsolepScrollScreenBuffer, 537 25
ConsolepSetTextAttribute, 538 26
ConsolepSetFont, 539 27
ConsolepSetIcon, 540 28
ConsolepReadConsole, 541 29
ConsolepWriteConsole, 542 30
ConsolepDupHandle, 543 31
ConsolepCloseHandle, 544 32
ConsolepVerifyIoHandle, 545 33
ConsolepAlloc, 546 34
ConsolepFree, 547 35
ConsolepGetTitle, 548 36
ConsolepSetTitle, 549 37
ConsolepCreateScreenBuffer, 550 38
ConsolepInvalidateBitmapRect, 551 39
ConsolepVDMOperation, 552 40
ConsolepSetCursor, 553 41
ConsolepShowCursor, 554 42
ConsolepMenuControl, 555 43
ConsolepSetPalette, 556 44
ConsolepSetDisplayMode, 557 45
ConsolepRegisterVDM, 558 46
ConsolepGetHardwareState, 559 47
ConsolepSetHardwareState, 560 48
ConsolepGetDisplayMode, 561 49
ConsolepAddAlias, 562 50
ConsolepGetAlias, 563 51
ConsolepGetAliasesLength, 564 52
ConsolepGetAliasExesLength, 565 53
ConsolepGetAliases, 566 54
ConsolepGetAliasExes, 567 55
ConsolepExpungeCommandHistory, 568 56
ConsolepSetNumberOfCommands, 569 57
ConsolepGetCommandHistoryLength, 570 58
ConsolepGetCommandHistory, 571 59
ConsolepSetCommandHistoryMode, 572 60
ConsolepGetCP, 573 61
ConsolepSetCP, 574 62
ConsolepSetKeyShortcuts, 575 63
ConsolepSetMenuClose, 576 64
ConsolepNotifyLastClose, 577 65
ConsolepGenerateCtrlEvent, 578 66
ConsolepGetKeyboardLayoutName, 579 67
ConsolepMaxApiNumber 580 68
Btw...there is one thing i would like to know.
ConsolepCloseHandle have a enumeration of 34 (It starts with 2 and not 0 as i thought) which gives me a result of 020222 . The values of those tables are fixed on all Windows versions ?
Asside my sources of win200 and winNT i found very few info about it. But i´m not sure i fully understood the behavior of those tables.
http://j00ru.vexillium.org/?p=349&lang=en
http://www.ivanlef0u.tuxfamily.org/?cat=1&paged=2
https://github.com/mirror/processhacker/blob/master/1.x/trunk/ProcessHacker.Native/Api/NativeDefinitions.cs
http://gate.upm.ro/os/LABs/Windows_OS_Internals_Curriculum_Resource_Kit-ACADEMIC/WindowsResearchKernel-WRK/WRK-v1.2/public/sdk/inc/ntcsrmsg.h
http://www.ivanlef0u.tuxfamily.org/?p=188
http://forum.sysinternals.com/topic15457.html
https://code.google.com/p/ontl/source/browse/branches/x64/ntl/nt/csr.hxx?r=67
http://j00ru.vexillium.org/csrss_list/api_table.html