Welcome to the new Woodmann RCE Messageboards Regroupment
Please be patient while the rest of the site is restored.

To all Members of the old RCE Forums:
In order to log in, it will be necessary to reset your forum login password ("I forgot my password") using the original email address you registered with. You will be sent an email with a link to reset your password for that member account.

The old vBulletin forum was converted to phpBB format, requiring the passwords to be reset. If this is a problem for some because of a forgotten email address, please feel free to re-register with a new username. We are happy to welcome old and new members back to the forums! Thanks.

All new accounts are manually activated before you can post. Any questions can be PM'ed to Kayaker.

CsrPortHandle Different when Run Within Ollydbg and Outside of it

Found a bug in OllyDbg? Post a report here.
Locked
blabberer
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

CsrPortHandle Different when Run Within Ollydbg and Outside of it

Post by blabberer »

i was poking around some csrss stuff and i happened to notice some thing peculiar

in ollydbg 1.10 as well as ollydbg 2.01(alpha 4) the latest release

it seems if i run a console app inside ollydbg the console app gets a Different CsrPortHandle and if i run the same app out of ollydbg it gets a different CsrPortHandle

ms debuggers viz cdb or windbg does not display this phenomenon

googled around for an explanation but cant find one

so this phenomenon can possibly be used as an anti debug measure ?? targeting ollydbg

i mailed oleh about the phenomenon


below is a snippet that shows the phenomenon compile and
run the exe out of ollydbg will get CsrPortHandle as 0x7ec
run within ollydbg CsrPortHandle will be 0x18

for windows xp - sp3 (haven't checked in any other os )

also attached a screen shot of different outcomes

Code: Select all


#define UNICODE

#include <stdio.h>

#include <tchar.h>

#include <windows.h>

#include <winternl.h>

typedef struct _CLIENT_ID {

	HANDLE UniqueProcess;

	HANDLE UniqueThread;

} CLIENT_ID, *PCLIENT_ID;

typedef struct _WRITE_CONSOLEA_SUPPORT {

	USHORT		DataLength;

	USHORT		TotalLength;

	USHORT		Type;

	USHORT		DataInfoOffset;

	CLIENT_ID	ClientId;

	ULONG64		DoNotUseThisField;

	ULONG		MessageId;

	ULONG		CallBackId;

	ULONG64		NoUse;

	ULONG		ConsoleHandle;

	HANDLE		StdHandle;

	char		MsgBuff[0x50];

	PCHAR		MsgBuffAddress;

	ULONG		MsgBuffSize;

	ULONG		NoUse1;

	BYTE		Flag;

	BYTE		Pad0;

	BYTE		Pad1;

	BYTE		Pad2;

	ULONG		NoUse2;

	ULONG		NoUse3;

} WRITE_CONSOLEA_SUPPORT, *PWRITE_CONSOLEA_SUPPORT;

typedef 

__kernel_entry 

NTSTATUS

(NTAPI  *pfnNtQueryInformationProcess )	(

	IN HANDLE ProcessHandle,

	IN PROCESSINFOCLASS ProcessInformationClass,

	OUT PVOID ProcessInformation,

	IN ULONG ProcessInformationLength,

	OUT PULONG ReturnLength OPTIONAL

	);

typedef

__kernel_entry

NTSTATUS

( NTAPI	*pfnNtRequestWaitReplyPort )	(

	IN HANDLE CsrPortHandle,

	IN PWRITE_CONSOLEA_SUPPORT wcsin,

	OUT PWRITE_CONSOLEA_SUPPORT wcsout

	);

typedef

__kernel_entry

NTSTATUS

( NTAPI *pfnCsrNewThread ) (
							void
							);

int _tmain(void)

{

	printf(

		"lets call some syscall and see it in kd\n"

		);

	HANDLE CurrentStdHandle;

	if ( ( CurrentStdHandle = GetStdHandle(

		STD_OUTPUT_HANDLE

		) ) == INVALID_HANDLE_VALUE) {

			printf(

				"GetStdHandle Failed with %08x \n" ,

				GetLastError()

				);

			return 0;

	}

	printf (

		"CurrentStdHandle is %08x\n",

		CurrentStdHandle

		);

	DWORD CurrentPid = GetCurrentProcessId();

	printf(

		"current process id is %08x\n",

		CurrentPid

		);

	HANDLE CurrentProcess;

	if ( ( CurrentProcess = OpenProcess (

		PROCESS_QUERY_INFORMATION,

		FALSE,

		CurrentPid

		)) == NULL ) {

			printf (

				"OpenProcess(CurrentPid) Failed with %08x\n",

				GetLastError()

				);

			CloseHandle(

				CurrentStdHandle

				);

			return 0;

	}

	printf (

		"OpenProcess Returned Handle %08x\n",

		CurrentProcess

		);

	pfnNtQueryInformationProcess NtQueryInformationProcess;

	pfnNtRequestWaitReplyPort NtRequestWaitReplyPort;

	pfnCsrNewThread	CsrNewThread;

	if (( NtQueryInformationProcess = ( pfnNtQueryInformationProcess )GetProcAddress(

		LoadLibrary(L"ntdll.dll"),

		"NtQueryInformationProcess"

		) ) == NULL ) { 

			printf (

				"Getproc NtQueryInfo Failed returned %08x\n",

				GetLastError()

				);

			CloseHandle(

				CurrentStdHandle

				);

			CloseHandle(

				CurrentProcess

				);

			return 0;

	}

	printf(

		"ntQueryInformationProcess is found at %x\n",

		NtQueryInformationProcess

		);

	if (( NtRequestWaitReplyPort = (pfnNtRequestWaitReplyPort ) GetProcAddress (

		LoadLibrary(L"ntdll.dll"),

		"NtRequestWaitReplyPort"

		) ) == NULL ) {

			printf (

				"Getproc NtQueryInfo Failed returned %08x\n",

				GetLastError()

				);

			CloseHandle(

				CurrentStdHandle

				);

			CloseHandle(

				CurrentProcess

				);

			return 0;

	}

	printf(

		"NtRequestWaitReplyPort is found at %x\n",

		NtRequestWaitReplyPort

		);

	if (( CsrNewThread = ( pfnCsrNewThread )GetProcAddress(

		LoadLibrary(L"ntdll.dll"),

		"CsrNewThread"

		) ) == NULL ) { 

			printf (

				"Getproc CsrNewThread Failed returned %08x\n",

				GetLastError()

				);

			CloseHandle(

				CurrentStdHandle

				);

			CloseHandle(

				CurrentProcess

				);

			return 0;

	}

	printf(

		"CsrNewThread is found at %x\n",

		CsrNewThread

		);

	HANDLE 	PortHandle = (**(PHANDLE *)((ULONG)CsrNewThread + 2)); 

	printf (

		"CsrPortHandle is %08x\n",

		PortHandle

		);


	PROCESS_BASIC_INFORMATION PBasicInfo;

	ULONG ReturnLength;

	NTSTATUS Status;

	Status = NtQueryInformationProcess(

		CurrentProcess,

		ProcessBasicInformation,

		&PBasicInfo,

		sizeof(PBasicInfo),

		&ReturnLength

		); 

	if( !NT_SUCCESS(Status) ) {

		printf(

			"NtQueryInformationProcess Failed With %08x\n",

			Status

			);

		CloseHandle(

			CurrentStdHandle

			);

		CloseHandle(

			CurrentProcess

			);

		return 0;

	}

	printf(

		"RTL_PROCESS_PARAMETERS For Current Process is at %08x\n"

		"Console Handle as per windbg display type info is %08x\n",

		PBasicInfo.PebBaseAddress->ProcessParameters,

		PBasicInfo.PebBaseAddress->ProcessParameters->Reserved2[0]

	);

	if (( SetConsoleTextAttribute	(

		CurrentStdHandle, 

		FOREGROUND_RED | FOREGROUND_INTENSITY

		) ) == 0) {

			printf(

				"SetConsoleTextAttribute Failed Returned %08x\n"

				"Following text wont have colours\n"

				);

	}

	WRITE_CONSOLEA_SUPPORT wcs;

	memset(

		&wcs,

		0,

		sizeof(wcs)

		);

	wcs.DataLength = 0x7c;

	wcs.TotalLength = 0x98;

	wcs.CallBackId = 0x2021e;

	wcs.ConsoleHandle = (ULONG)PBasicInfo.PebBaseAddress->ProcessParameters->Reserved2[0];

	wcs.StdHandle = CurrentStdHandle;

	strcpy_s (

		wcs.MsgBuff ,

		80,

		"Put on Black Helmets Entering a CoalMine Can be Fatal Blue Screen Anytime\n"

		);

	wcs.MsgBuffAddress = (PCHAR)&wcs.MsgBuff;

	wcs.MsgBuffSize = sizeof("Put on Black Helmets Entering a CoalMine Can be Fatal Blue Screen Anytime\n");

	wcs.Flag =1;



	Status = NtRequestWaitReplyPort(

		PortHandle,

		&wcs,

		&wcs

		);

	if( !NT_SUCCESS(Status) ) {

		printf(

			"NtRequestReplyPortWith Handle %08x Failed\n",

			PortHandle

			);



		CloseHandle(

			CurrentStdHandle

			);

		CloseHandle(

			CurrentProcess

			);

		return 0;

	}


	CloseHandle(

		CurrentStdHandle

		);

	CloseHandle(

		CurrentProcess

		);

	return 0;

}
Attachments
CsrPortHandle.jpg
blabberer
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post by blabberer »

Testing this with ida fre 5 debugger yields same result like ollydbg ie
CsrPortHandle Returned is 0x18 not 0x7ec
borland td32 also yields 0x18 not 0x7ec so probably ms knows something better it seems
Attachments
TD32_CsrPortHandle.jpg
idafre_5_debugger_CsrPorthandle.jpg
blabberer
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post by blabberer »

this phenomenon is probably because windbg and cdb sets bInheritHandle option in CreateProcess To True while ollydbg ida td32 set this to false

a sample output fro all three debuggers broken On CreateProcess
for windbg a commented output for CreateProcessAndAttach2Wide is shown below as well as CreateProcessW
the other 2 debuggers use CreateProcessA

Code: Select all


0:010> ~10kbN
 # ChildEBP RetAddr  Args to Child              
00 00b9fbf8 022f0f21 00000000 009e1d38 00000000 kernel32!CreateProcessW
01 00b9fcb0 021308ab 009e7a88 009e1d38 00b9fd1c dbgeng!LiveUserDebugServices::CreateProcessW+0x241
02 00b9fcf0 020fc3e9 009e1d38 00b9fd1c 00000000 dbgeng!LiveUserTargetInfo::StartCreateProcess+0xfb
03 00b9fd40 0102af55 009ead1c 00000000 00000000 dbgeng!DebugClient::CreateProcessAndAttach2Wide+0xd9
04 00b9ffa4 0102b5ab 00000000 00000000 00b9ffec windbg!StartSession+0x445
05 00b9ffb4 7c80b729 00000000 7e428dd9 004101ee windbg!EngineLoop+0x1b
06 00b9ffec 00000000 0102b590 00000000 00000000 kernel32!BaseThreadStart+0x37

0:010> .frame /r 3

03 00b9fd40 0102af55 dbgeng!DebugClient::CreateProcessAndAttach2Wide+0xd9
eax=02297966 ebx=00000000 ecx=02337490 edx=7c802336 esi=004101ee edi=7e428dd9
eip=020fc3e9 esp=00b9fcf8 ebp=00b9fd40 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
dbgeng!DebugClient::CreateProcessAndAttach2Wide+0xd9:
020fc3e9 8945f0          mov     dword ptr [ebp-10h],eax ss:0023:00b9fd30=00000000

0:010> r $t0 = 00b9fd40    <----------- ebp for frame

0:010> ln poi poi poi (@$t0+8) vtable This Pointer 

(02102610)   dbgeng!DebugClient::QueryInterface   |  (02102620)   dbgeng!DebugClient::Release
Exact matches:
    dbgeng!DebugClient::QueryInterface = <no type information>

0:010> dq $t0+c l1
00b9fd4c  00000000`00000000  process server is NULL so Local Process ULONG64 

0:010> du /c 100 poi(@$t0+0x14)
009e1d38  ""C:\Documents and Settings\Admin\My Documents\Visual Studio 2008\Projects\syscalltest\syscalltest\syscalltest.exe"" command line

0:010> ? poi (windbg!g_DebugCreateOptions+0);? poi (windbg!g_DebugCreateOptions+4);? poi (windbg!g_DebugCreateOptions+8);? poi (windbg!g_DebugCreateOptions+0xc);
Evaluate expression: 2 = 00000002
Evaluate expression: 1 = 00000001
Evaluate expression: 0 = 00000000
Evaluate expression: 0 = 00000000
0:010> .echo so The new process will inherit system handles from the debugger or process server. see DebugCreateOptions->EngCreateFlags

0:010> dd /c 1 (@$t0+0x1c) l5

00b9fd5c  00000010 size of DebugCreateOptions
00b9fd60  00000000
00b9fd64  00000000
00b9fd68  00000000
00b9fd6c  00000000


0:010> dd /c 1 00b9fbf8  l10   Stack For CreateProcessW .frame 0
00b9fbf8  02297cd5 
00b9fbfc  022f0f21
00b9fc00  00000000
00b9fc04  009e1d3800 "C:\Documents and Settings\Admin\My Documents\Visual Studio 2008\Projects\syscalltest\syscalltest\syscalltest.exe"
00b9fc08  00000000
00b9fc0c  00000000
00b9fc10  00000001 1 = TRUE For Inherit Handles
00b9fc14  00000402 402 = CREATE_UNICODE_ENVIRONMENT | DEBUG_ONLY_THIS_PROCESS
00b9fc18  00000000
00b9fc1c  00000000
00b9fc20  00b9fc30 si
00b9fc24  00b9fca0 pi


Ollydbg 1.10 

0:000> kb
ChildEBP RetAddr  Args to Child              
0013c450 0047795d 00000000 0013c908 00000000 kernel32!CreateProcessA
WARNING: Stack unwind information not available. Following frames may be wrong.
0013e1b8 004341e8 0013e288 ffffffff 0013f50c ollydbg!OpenEXEfile+0x641
0013f4a4 7e418734 00280328 00000111 000007da ollydbg!Animate+0x2710
0013f4d0 7e418816 004323d4 00280328 00000111 USER32!InternalCallWinProc+0x28
0013f538 7e4189cd 00000000 004323d4 00280328 USER32!UserCallWinProcCheckWow+0x150
0013f598 7e4196c7 0013f5c0 00000001 0013ff88 USER32!DispatchMessageWorker+0x306
0013f5a8 00439442 0013f5c0 00000000 004b00c4 USER32!DispatchMessageA+0xf
0013ff88 004ad357 00400000 00000000 00561ef6 ollydbg!Go+0x4a2e
0013ffc0 7c817077 013af6ee 013af736 7ffd9000 ollydbg!Createpatchwindow+0xe0f7
0013fff0 00000000 00401000 00000000 78746341 kernel32!BaseProcessStart+0x23
0:000> dd /c 1 0013c450 l8
0013c450  004a6c4f
0013c454  0047795d
0013c458  00000000
0013c45c  0013c908
0013c460  00000000
0013c464  00000000
0013c468  00000000
0013c46c  04000032  NORMAL_PRIORITY_CLASS | DEBUG_ONLY_THIS_PROCESS || CREATE_DEFAULT_ERROR_MODE CREATE_NEW_CONSOLE
0:000> da /c 100 0013c908
0013c908  ""C:\Documents and Settings\Admin\My Documents\Visual Studio 2008\Projects\syscalltest\syscalltest\syscalltest.exe""

IDAFRE5

0:000> kb
ChildEBP RetAddr  Args to Child              
0013df00 0196e578 0013f614 00000000 00000000 kernel32!CreateProcessA
WARNING: Stack unwind information not available. Following frames may be wrong.
0013e47c 0196589d 0013f614 00000000 0013ee14 win32_user!Ordinal2+0xe578
0013ecc0 0196ba79 0013f614 0013f214 0013ee14 win32_user!Ordinal2+0x589d
0013edf0 004db051 0013f614 0013f214 0013ee14 win32_user!Ordinal2+0xba79
0013fa18 004f1f4c 00000000 00000000 00000000 idag!StrchooseFinalize+0x13099
0013fa7c 0044c5d0 01073394 400e7548 01073904 idag!StrchooseFinalize+0x29f94
0013fbc0 400387f2 01073904 400e71a6 0013fe3c idag!GroverFinalize+0x38ebc
0013fd38 4010a9a8 7e418734 00220308 00000020 rtl60!ClassesTBasicActionExecute$qqrv+0x12
0013fd80 0044aa16 01180fd5 01031ecc 4010a623 vcl60!ControlsTWinControlWndProc$qqrr17MessagesTMessage+0x15c
0013fdbc 4003947a 00000111 000000f6 00000000 idag!GroverFinalize+0x37302
0013fdd4 7e418734 00220308 00000111 000000f6 rtl60!ClassesTDataModuleWriteHeight$qqrp15ClassesTWriter+0x22
0013fe00 7e418816 01180fd5 00220308 00000111 user32!InternalCallWinProc+0x28
0013fe68 7e4189cd 00000000 01180fd5 00220308 user32!UserCallWinProcCheckWow+0x150
0013fec8 7e4196c7 0013fef8 00000001 0013ff44 user32!DispatchMessageWorker+0x306
0013fed8 400f5834 0013fef8 0013ff00 00000000 user32!DispatchMessageA+0xf
0013ff44 00402273 00000000 00571034 00171ef5 vcl60!FormsTApplicationProcessMessage$qqrr6tagMSG+0x88
0013ff88 00567abf 00400000 00000000 00171ef5 idag!_GetExceptDLLinfo+0xbca
0013ffc0 7c817077 00def6ee 00def734 7ffd5000 idag!Droptargetinitialization$qqrv+0xc59f
0013fff0 00000000 00401650 00000000 78746341 kernel32!BaseProcessStart+0x23
0:000> dd /c 1 0013df00 l8
0013df00  0013df18
0013df04  0196e578
0013df08  0013f614
0013df0c  00000000
0013df10  00000000
0013df14  00000000
0013df18  00000000
0013df1c  04000023   NORMAL_PRIORITY_CLASS | DEBUG_ONLY_THIS_PROCESS | DEBUG_PROCESS | CREATE_DEFAULT_ERROR_MODE



remove probability it is the cause i ran another round and this time i edited the arg in stack for idafre5 and output comes out to 0x7ec instead of 0x18

see snap
Attachments
bInheritHandleSetToTrueForIdag5.jpg
User avatar
Kayaker
Posts: 4169
Joined: Thu Oct 26, 2000 11:00 am

Post by Kayaker »

Was looking at this a bit. You can see this in Process Explorer as well.

First, set up ProcEx to view handles (View/Lower Pane View/Handles), as well as unnamed handles (View/Show Unnamed Handles and Mappings).

Now open 3 instances of cmd.exe, one standard as opened under Windows, one under Olly/etc., and one under WinDbg.

Click on each cmd.exe process in Process Explorer and view the Port handle in the lower pane.

The standard cmd.exe has a Port handle of 0x18 (oops?), so does the one under Olly, but the one under WinDbg is, as reported, 0x7EC.

Strange though, ProcEx reports a Port handle of 0x18 when cmd is run outside of any debugger, whereas you found that CsrNewThread returns a CsrPortHandle value of 0x7EC. Not sure why, but if you look at just about any other gui process, they all seem to have a default 0x18 Port handle.
blabberer
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post by blabberer »

i see so there is one more twist to the tale :)
well who knows whats right

anyway i found a bit of time to check this in win7 and in win7 it is completely different beast :) the leopard has even changed the spots :)

CsrNewThread Which pointed to Some RegisterTerminateThread in xp does not exist in win7 google says via geoff chappel that this api was discontinued from vista sp1 onwards

so what disassemble some other func and find xref and leech is that something new or are you a noob you may ask ?

well CsrClientCallServer is a function common in both os that pushes CsrPortHandle and leech we can

but boy the win7 coders really put in a lot of work to evade us it seems :)

the CsrPorthandle in win7 comes back with This End of pipe Is not open to blah blah


the whole Csr Stuff that console uses seems to be shifted to kernel32

and kernel32!ConsoleLpcHandle is used this handle isnt available readily yep convoluted search can grab it


but it seems this handle is filled up During LdrinitializeProcess via NtConnectPort using a basenamedObject

viewable via windbg !object \

viz \\RPC Control\Console-"surprise here the other Csrporthandle From Ntdll is used as string like -0x00000cf6-lpc-handle "

it seems to be 0x1c always ie call NtRequestReplyPort WIth (0x1c, &buff , &buff)

i cooked an NtConnectPort but i get back 0xc0000034 status_obj_name_not_found

probably i have to tweak the Security Qos crap arg a bit or tweak other params

well if these hurdles are passed the actual size and length of NtRequestReplyPort have changed too it seems :) reduced by 4 bytes

so it is 78 and 94 instead of 7c and 98 :)

the dll << 16 | routine no stuff which yields 0x2021e

has been changed to just routine no

ie now these Csr things probably take just 0x1e instead of 0x2021e

also the position of msgbuff in the struct has changed (come forward by 4 bytes ) and Stdhandle is embedded after msgbuff

quiet a lot of hacks to be done to simulate a printf weeee

and hand spleunking stuff in debugger shows win7/ollydbg /windbg/ also has this peculiarities

the handle seems to 0x14 outside and 0x18 inside or viceversa dont remember now

anyway it would be good to solve the mystery :)
Locked