PDA

View Full Version : Took a bit.. sorry


BanMe
June 18th, 2010, 14:17
well i am back.. be it for better or worse... I owe a little something to someone first.. but that will be dealt with..

so im still working on this little toy and the newest feature i am adding to it is remote veh takeover... with a dynamic hook handler (page_guard,or int3hooks) I know I got a bit of work left in the int3 part of it adding the function to write a int3 for instance but w/e, i am after just opinions on this approach....

its basicly write HANDLER to process reference HANDLER in injected code to install VEH by locating the VehListHead in RtlAddVectoredExceptionHandler and using InsertHeadList..ive redone basicly everything and am nearing release of v3...
Code:

typedef struct _SIN_REQUEST_MESSAGE
{
PORT_MESSAGE Header;
SIN_REQUEST_TYPE ReqType;
}SIN_REQUEST_MESSAGE,*PSIN_REQUEST_MESSAGE;

typedef struct _SIN_REQUEST_VEH_TAKEOVER
{
SIN_REQUEST_MESSAGE Header;
ULONG HandleExceptionType;
ULONG TargetFunc
ULONG HookFunc
ANSI_STRING ProcessName;
}SIN_REQUEST_VEH_TAKEOVER,*PSIN_REQUEST_VEH_TAKEOVER;

typedef struct _VEH_HIJACK_SETUP
{
RTLALLOCATEHEAP Alloc;
RTLENCODEPOINTER Encode;
RTLENTERCRITICALSECTION CriticalEnter;
RTLLEAVECRITICALSECTION CriticalLeave;
ULONG RtlpVectoredExceptionLock;
ULONG VehListHead;
void *VectoredHandler;
}VEH_HIJACK_SETUP,*PVEH_HIJACK_SETUP;
...
case HK_REMOTE_VEH_TAKEOVER:
{
ReqVehHook = (SIN_REQUEST_VEH_TAKEOVER*)ReqMessage;
if(SinSrvSetupVeHijack(&HijackInfo))
{
if(ReqVehHook->HandleExceptionType == 0)
{
if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&Unicode,&ReqVehHook->ProcessName,false)))
{
ClientId.UniqueProcess = GetPidByName(Unicode.Buffer);
ClientId.UniqueThread = 0;
if(NT_SUCCESS(NtOpenProcess(&TargetProc,PROCESS_ALL_ACCESS,0,&ClientId)))
{
Size = GetFunctionLength(HookHandler);
if(NT_SUCCESS(NtAllocateVirtualMemory(TargetProc,&HookLocation,0,(SIZE_T*)Size,MEM_COMMIT,PAGE_EXECUTE_READWRITE)))
{
if(NT_SUCCESS(NtWriteVirtualMemory(TargetProc,HookLocation,HookHandler,Size,&Address)))
{
if(NT_SUCCESS(NtWriteVirtualMemory(TargetProc,HookLocation,ReqVehHook->TargetFunc,sizeof(ULONG),&Address)))
{
if(NT_SUCCESS(NtWriteVirtualMemory(TargetProc,((PVOID)((ULONG)HookLocation+sizeof(ULONG)*10)),ReqVeh Hook->HookFunc,&Address)))
{
Size = GetFunctionLength(SinSrvSetupVeHijack);
if(NT_SUCCESS(NtAllocateVirtualMemory(TargetProc,&HandlerLocation,0,(SIZE_T*)Size,MEM_COMMIT,PAGE_EXECUTE_READWRITE)))
{
if(NT_SUCCESS(NtWriteVirtualMemory(TargetProc,HandlerLocation,SinSrvSetupVeHijack)))
{
HijackInfo.VectoredHandler = HandlerLocation;
if(NT_SUCCESS(RtlCreateUserThread(TargetProc,0,false,0,0,0,(PUSER_THREAD_START_ROUTINE)HandlerLocati on,&HijackInfo,TargetThread,&ClientId)))
{
break;
}
}
}
}
}
}
}
}
}
break;
}
else
{
//int3installer
}
}
break;
....
bool SinSrvSetupVeHijack(__out VEH_HIJACK_SETUP*HijackSetup)
{
ULONG Address = 0;
BYTE FindThis[] = {0x89, 0x06, 0x00, 0x04};
BYTE FindThis2[] = {0x89 ,0x46, 0x0, 0x5};
HijackSetup->Alloc = (RTLALLOCATEHEAP)Native_GetApi(L"ntdll.dll","RtlAllocateHeap";
HijackSetup->CriticalEnter = (RTLENTERCRITICALSECTION)Native_GetApi(L"ntdll.dll","RtlEnterCriticalSection";
HijackSetup->Encode = (RTLENCODEPOINTER)Native_GetApi(L"ntdll.dll","RtlEncodePointer";
HijackSetup->CriticalLeave = (RTLLEAVECRITICALSECTION)Native_GetApi(L"ntdll.dll","RtlLeaveCriticalSection";
Address = (ULONG)Native_GetApi(L"ntdll.dll","RtlAddVectoredExceptionHandler";
HijackSetup->VehListHead = (ULONG_PTR)FindCode((ULONG)Address,(BYTE*)&FindThis);
HijackSetup->RtlpVectoredExceptionLock = FindCode(Address,(BYTE*)&FindThis2);
if(!HijackSetup->Alloc && !HijackSetup->CriticalEnter && !HijackSetup->Encode && !HijackSetup->CriticalLeave && !HijackSetup->VehListHead && !HijackSetup->RtlpVectoredExceptionLock)
{
return false;
}
return true;
}
void SinSrvHijackVEH(VEH_HIJACK_SETUP*HijackSetup)
{
__asm
{
RTL_HEAP:
nop
nop
nop
nop
RTL_ENCODED:
nop
nop
nop
nop
}
HijackSetup->Alloc(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap,0,sizeof(RTL_VECTORED_EXCEPTION_HANDLER));
__asm
{
lea ecx, RTL_HEAP
mov dword ptr[ecx],eax
}
if(NT_SUCCESS(HijackSetup->CriticalEnter((PRTL_CRITICAL_SECTION)HijackSetup->RtlpVectoredExceptionLock)))
{
__asm
{
lea edx,HijackSetup
push eax
push edx
push [edx]HijackSetup.VectoredHandler
call [edx]HijackSetup.Encode
cmp eax, 0
je Fail
mov ecx,eax
pop edx
pop eax
add eax,8
mov dword ptr[eax],ecx
mov ecx,dword ptr[edx]HijackSetup.VehListHead
push ecx
lea eax,RTL_HEAP
push eax
call InsertHeadList
}
if(NT_SUCCESS(HijackSetup->CriticalLeave((PRTL_CRITICAL_SECTION)HijackSetup->RtlpVectoredExceptionLock)))
{
return;
}
Fail:
return;
}
}
__declspec(naked) ULONG HookHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
__asm
{
TargetFuncs:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
HookFuncs:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
Int3Buffer:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
xor ecx,ecx
mov ebx,dword ptr [ExceptionInfo]
mov eax,dword ptr[ebx]ExceptionInfo.ExceptionRecord.ExceptionCode
cmp eax,0x80000001
je FindGuardPoint
mov eax,dword ptr[ebx]ExceptionInfo.ExceptionRecord.ExceptionCode
cmp eax,0x80000003
je FindBreakPoint
FindGuardPoint:
cmp ecx,10
je ContinueSearch
mov eax,4
imul eax,ecx
lea edx,TargetFuncs
mov esi,dword ptr[edx+eax]
cmp byte ptr [esi],0x90
je ContinueSearch
cmp esi,[ebx]ExceptionInfo.ContextRecord.Eip
je FoundGp
inc ecx
jmp FindGuardPoint
FoundGp:
lea esi,HookFuncs
mov esi,dword ptr [esi+eax]
cmp byte ptr[esi],0x90
mov dword ptr[ebx]ExceptionInfo.ContextRecord.Eip,esi
mov eax,-1
ret
FindBreakPoint:
cmp ecx,10
je ContinueSearch
mov eax,4
imul eax,ecx
lea esi,Int3Buffer
mov edx,dword ptr[esi+eax]
cmp byte ptr[edx],0x90
je ContinueSearch
cmp edx,dword ptr[ebx]ExceptionInfo.ContextRecord.Eip
je FoundBp
inc ecx
inc ecx
jmp FindBreakPoint
FoundBp:
inc ecx
mov eax,4
imul eax,ecx
mov ecx,dword ptr[esi+eax]
cmp byte ptr[ecx],0x90
je ContinueSearch
mov ebx,[ebx]ExceptionInfo.ContextRecord.Eip
mov dword ptr [ebx],ecx
mov eax,-1
ret
ContinueSearch:
mov eax,0
ret
}
}

j00ru
June 18th, 2010, 19:16
Hey BanMe!
Good work, nice to see you posting here again ;>
Keep the fire burning!

BanMe
June 18th, 2010, 19:38
Yes I am alive,and well and at peace with what I am, and what I am not.

Indy
June 18th, 2010, 19:55
BanMe
Why use self realization, if there is api RtlAddVectoredExceptionHandler() ?
-
Cookies can not be determined remotely, but you can lock critical section RtlpCalloutEntryLock. Then the threads will enter the wait state at the opening event. You can get their context and further to control the behavior

BanMe
June 18th, 2010, 20:21
Quote:
Why use self realization, if there is api RtlAddVectoredExceptionHandler() ?

Code:

if(FirstHandler)
{
InsertHeadList(Head,Entry);
}
else
{
InsertTailList(Head,Entry);
}

This code is in RtlAddVectoredExceptionHandler..

replacement for above code.. with some fixs..
Code:

case SIN_REMOTE_VEH_TAKEOVER:
{
ReqVehHook = (SIN_REQUEST_VEH_TAKEOVER*)ReqMessage;
if(SinSrvSetupVeHijack(&HijackInfo))
{
if(ReqVehHook->HandleExceptionType == 0)
{
if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&Unicode,&ReqVehHook->ProcessName,false)))
{
ClientId.UniqueProcess = GetPidByName(Unicode.Buffer);
ThisEntry = SinSrvLocateClientByPid(ClientId.UniqueProcess);
if(!ThisEntry)
{
Native_AllocateHeap(MessageDataBuffer,sizeof(SIN_CLIENT_ENTRY),MEMORY_ALLOCATION_ALIGNMENT);
ThisEntry->ProcessId = ClientId.UniqueProcess;
InsertHeadList(&ClientListHead,(PLIST_ENTRY)&ThisEntry->ClientList);
ClientId.UniqueThread = 0;
if(!NT_SUCCESS(NtOpenProcess(&ThisEntry->Process,PROCESS_ALL_ACCESS,0,&ClientId)))
{
break;
}
ThisEntry->ServerThread = (HANDLE)NtCurrentThreadId();
Size = GetFunctionLength(HookHandler);
if(NT_SUCCESS(NtAllocateVirtualMemory(ThisEntry->Process,&HandlerLocation,0,(SIZE_T*)Size,MEM_COMMIT,PAGE_EXECUTE_READWRITE)))
{
if(NT_SUCCESS(NtWriteVirtualMemory(ThisEntry->Process,HandlerLocation,HookHandler,Size,&Address)))
{
ThisEntry->HookInfo.Handler = HijackInfo.VectoredHandler = HandlerLocation;
if(ThisEntry->HookInfo.NumTargets == 0)
{
if(NT_SUCCESS(NtWriteVirtualMemory(ThisEntry->Process,HandlerLocation,(PVOID)ReqVehHook->TargetFunc,sizeof(ULONG),&Address)))
{
ThisEntry->HookInfo.NumTargets++;
if(NT_SUCCESS(NtWriteVirtualMemory(ThisEntry->Process,((PVOID)((ULONG)HandlerLocation+sizeof(ULONG)*10)),(PVOID)ReqVehHook->HookFunc,sizeof(ULONG),&Address)))
{
ThisEntry->HookInfo.NumHooks++;
goto Install;
}
}
}
}
}
break;
}
else
{
if(NT_SUCCESS(NtWriteVirtualMemory(ThisEntry->Process,((PVOID)((ULONG)ThisEntry->HookInfo.Handler+sizeof(ULONG)*ThisEntry->HookInfo.NumTargets)),(PVOID)ReqVehHook->TargetFunc,sizeof(ULONG),&Address)))
{
ThisEntry->HookInfo.NumTargets++;
if(NT_SUCCESS(NtWriteVirtualMemory(ThisEntry->Process,((PVOID)((ULONG)ThisEntry->HookInfo.Handler+sizeof(ULONG)*10+sizeof(ULONG)*ThisEntry->HookInfo.NumHooks)),(PVOID)ReqVehHook->HookFunc,sizeof(ULONG),&Address)))
{
ThisEntry->HookInfo.NumHooks++;
break;
}
}
break;
}
Install:
Size = GetFunctionLength(SinSrvSetupVeHijack);
if(NT_SUCCESS(NtAllocateVirtualMemory(ThisEntry->Process,&HookLocation,0,(SIZE_T*)Size,MEM_COMMIT,PAGE_EXECUTE_READWRITE)))
{
if(NT_SUCCESS(NtWriteVirtualMemory(ThisEntry->Process,HookLocation,SinSrvHijackVEH)))
{
if(NT_SUCCESS(NtQueryVirtualMemory(ThisEntry->Process,(PVOID)ReqVehHook->TargetFunc,MemoryBasicInformation,&mbi,sizeof(mbi),0)))
{
if(mbi.AllocationProtect & PAGE_NOACCESS)
{
if(NT_SUCCESS(RtlCreateUserThread(ThisEntry->Process,0,false,0,0,0,(PUSER_THREAD_START_ROUTINE)(HandlerLocation+(sizeof(ULONG)*10)*3),&HijackInfo,TargetThread,&ClientId)))
{
break;
}
}
else
{
if(NT_SUCCESS(NtProtectVirtualMemory(ThisEntry->Process,ReqVehHook->TargetFunc,&Size,PAGE_NOACCESS,&oProt)))
{
if(NT_SUCCESS(RtlCreateUserThread(ThisEntry->Process,0,false,0,0,0,(PUSER_THREAD_START_ROUTINE)(HandlerLocation+(sizeof(ULONG)*10)*3),&HijackInfo,TargetThread,&ClientId)))
{
break;
}
}
}
}
}
}
}
break;
}
else//int3Hooks...
{
}
}
else
{
break;
}

}


Also Indy the use of the barrier methodology is a good idea for other things maybe I will implement a generic remote critical section barrier Request.. :]

Code:

//structs and good explanation seen here hxxp://msdn.microsoft.com/en-us/magazine/cc164040.aspx#S7
struct _RTL_CRITICAL_SECTION_DEBUG
{
WORD Type;
WORD CreatorBackTraceIndex;
RTL_CRITICAL_SECTION *CriticalSection;
LIST_ENTRY ProcessLocksList;
DWORD EntryCount;
DWORD ContentionCount;
DWORD Spare[ 2 ];
}
struct RTL_CRITICAL_SECTION
{
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
LONG LockCount;
LONG RecursionCount;
HANDLE OwningThread;
HANDLE LockSemaphore;
ULONG_PTR SpinCount;
};
RTL_CRITICAL_SECTION *PebLock;
PPEB Peb = NtCurrentPeb();
PebLock = Peb->LoaderLock;
PebLock = (PebLock->DebugInfo->ProcessLockList.flink != 0) ? PebLock->DebugInfo->ProcessLockList.flink : 0;
PebLock = (PebLock->DebugInfo->ProcessLockList.flink != 0) ? PebLock->DebugInfo->ProcessLockList.flink : 0;
if(PebLock)
//here should be RtlpCallOutEntryLock in PebLock...
RtlEntryCriticalSection(PebLock);

BanMe
June 26th, 2010, 00:36
some future types to look forward to?
Code:

typedef enum _SIN_REQUEST_TYPE
{
SIN_INJECT_CLIENT,
SIN_INJECT_DLL,
SIN_RUN_CODE,
SIN_REMOTE_HOOK,
SIN_REMOTE_VEH_TAKEOVER,
//SIN_REMOTE_SEH_TAKEOVER
}SIN_REQUEST_TYPE;

//and the first few are done only RUN_CODE(thread injection) and a bit one remote_hook..
this one is still in need of a few fixs..
case SIN_INJECT_CLIENT:
{
ReqInjectClient = (SIN_REQUEST_INJECT_CLIENT*)&ReqMessage->ReqInfo.ReqInjectClient;
RtlInitAnsiString(&Ansi,ReqInjectClient->ProcessName);
if(NT_SUCCESS(Status))
{
RtlAnsiStringToUnicodeString(&Unicode,&Ansi,true);
ClientId.UniqueProcess = GetPidByName(Unicode.Buffer);
ThisEntry = SinSrvLocateClientByPid(ClientId.UniqueProcess);
if(!ThisEntry)
{
ThisEntry = (SIN_CLIENT_ENTRY*)Native_AllocateHeap(MessageDataBuffer,sizeof(SIN_CLIENT_ENTRY),MEMORY_ALLOCATION_ ALIGNMENT);
ThisEntry->ProcessId = ClientId.UniqueProcess;
InsertHeadList(&ClientListHead,(PLIST_ENTRY)&ThisEntry->ClientList);
ClientId.UniqueThread = 0;
//Status = RtlAdjustPrivilege(20,true,1,0);
if(SetDebugPrivileges() == 0)
{
InitializeObjectAttributes(&oa,0,OBJ_KERNEL_HANDLE,0,0);
Status = NtOpenProcess(&ReqData,PROCESS_ALL_ACCESS,&oa,&ClientId);
}
//Status = RtlAdjustPrivilege(20,false,1,0);
ThisEntry->Process = ReqData;
ThisEntry->ServerThread = (HANDLE)NtCurrentThreadId();
SinSrvClientConnectServer = (SINSRVCLIENTCONNECTSERVER)Native_GetApi(L"affectionate.dll","SinSrvClientConnectServer";
if(Native_GetPEInfo((char*)GetPebDll(L"affectionate.dll",&dos,&nt,&pe_opt,&pe_sec)== true)
{
if(Native_LoadShare((char*)GetPebDll(L"affectionate.dll",&dos,&nt,&pe_opt,pe_sec,BaseMessage->ClientInfo.ServerView.ViewBase)== true)
{
ThisEntry->ServerView = BaseMessage->ClientInfo.ServerView;
memcpy(ThisEntry->ServerView.ViewBase,SinSrvClientConnectServer,Native_GetImageSize(&dos,&nt,&pe_opt,pe_sec));
}
if(NT_SUCCESS(NtMapViewOfSection(ThisEntry->ServerView.SectionHandle,ThisEntry->Process,&ReqData,0,Size,0,&Address,ViewShare,SEC_COMMIT,PAGE_EXECUTE_READWRITE)))
{
}
}
}
}
break;
}


so I am going to take the path of modular design as the 'server' is a dll and I've made the 'basic' client tests all dlls as well.I am tinkering with a asm GUI controller client that can send commands to server..from usermode and process and view output from server or 'client' but..more to come..

BanMe
June 30th, 2010, 11:25
Client is Loaded at Static Base Address until I make it relocatable..also this is simple injection method it is not best but it gets the job done for now...
Code:

case SIN_INJECT_CLIENT:
{
ReqInjectClient = (SIN_REQUEST_INJECT_CLIENT*)&ReqMessage->ReqInfo.ReqInjectClient;
RtlInitAnsiString(&Ansi,ReqInjectClient->ProcessName);
RtlAnsiStringToUnicodeString(&Unicode,&Ansi,true);
ClientId.UniqueProcess = GetPidByName(Unicode.Buffer);
ThisEntry = SinSrvLocateClientByPid(ClientId.UniqueProcess);
if(!ThisEntry)
{
ThisEntry = (SIN_CLIENT_ENTRY*)Native_AllocateHeap(MessageDataBuffer,sizeof(SIN_CLIENT_ENTRY),MEMORY_ALLOCATION_ ALIGNMENT);
ThisEntry->ProcessId = ClientId.UniqueProcess;
ThisEntry->ServerThread = (HANDLE)NtCurrentThreadId();
ThisEntry->ServerView = BaseMessage->ClientInfo.ServerView;
InsertTailList(&ClientListHead,(PLIST_ENTRY)&ThisEntry->ClientList);
ClientId.UniqueThread = 0;
Status = RtlAdjustPrivilege(20L,true,0,&PrivHeld);
InitializeObjectAttributes(&oa,0,0,0,0);
Status = NtOpenProcess(&ReqData,PROCESS_ALL_ACCESS,&oa,&ClientId);
ThisEntry->Process = ReqData;
Status = RtlAdjustPrivilege(20L,false,0,&PrivHeld);
RtlInitAnsiString(&Ansi,"C:\\WINDOWS\\System32\\affectionate.dll";
//InitializeObjectAttributes(&oa,&Unicode,OBJ_CASE_INSENSITIVE,0,0);
Status = LdrFindEntryForAddress(GetPebDll(L"affectionate.dll",&Mod);
InitializeObjectAttributes(&oa,0,0,0,0);
Status = NtAllocateVirtualMemory(ThisEntry->Process,&HandlerLocation,0,(PSIZE_T)&Ansi.Length,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
Status = NtWriteVirtualMemory(ThisEntry->Process,HandlerLocation,(PVOID)Ansi.Buffer,(ULONG)Ansi.Length,&Size);
ReqData = (void*)Native_GetApi(L"kernel32.dll","LoadLibraryA";
Status = RtlCreateUserThread(ThisEntry->Process,0,false,0,0,0,(PUSER_THREAD_START_ROUTINE)ReqData,HandlerLocation,&ThisEntry->ThreadId,&ClientId);
Status = NtFreeVirtualMemory(ThisEntry->Process,&HandlerLocation,&Mod->SizeOfImage,MEM_RELEASE);
ReqData = Native_GetApi(L"affectionate.dll","SinSrvClientConnectServer";
Status = RtlCreateUserThread(ThisEntry->Process,0,false,0,0,0,(PUSER_THREAD_START_ROUTINE)ReqData,0,&ThisEntry->ThreadId,&ClientId);
}
break;//client already listed(this might be a hooked process and not a client have to add a check..)
}


heres the Gui controller's code
Code:

bool InitializeSinReqMessage(SIN_REQUEST_MESSAGE *ph,USHORT len,LPC_TYPE type,SIN_REQUEST_TYPE reqtype)
{
ph->Header.u1.s1.TotalLength = len;
ph->Header.u1.s1.DataLength = len - sizeof(PORT_MESSAGE);
ph->Header.u2.s2.Type = (USHORT)(type);
ph->Header.u2.s2.DataInfoOffset = 0;
ph->ReqType = reqtype;
return true;
}

//...
strcpy((char*)&ReqMessage.ReqInfo.ReqInjectClient.ProcessName,"explorer.exe";
InitializeSinReqMessage(&ReqMessage,sizeof(SIN_REQUEST_MESSAGE),LPC_NEW_MESSAGE,SIN_INJECT_CLIENT);
Status = NtRequestWaitReplyPort(PortHandle,(PORT_MESSAGE*)&ReqMessage,(PORT_MESSAGE*)&ReplyMessage);
if(!NT_SUCCESS(Status))
{
RtlInitUnicodeString(&Unicode,L"NtRequestWaitReplyPort Status:";
__leave;
}
//...


The actual client code needs some work on it but I've got 2 days off and a release should be somewhat soon..saturday maybe..

heres a bit from the client...much more to add...though...
Code:

RecvMessage = RtlAllocateHeap(RtlProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SIN_API_MESSAGE));
ReqMessage = RtlAllocateHeap(RtlProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SIN_REQUEST_MESSAGE));
ApiRecvMessage = *(SIN_API_MESSAGE*)RecvMessage;
ApiReqMessage = *(SIN_REQUEST_MESSAGE*)ReqMessage;
WaitForServer:
Status = NtWaitForSingleObject(CommEvent,FALSE,0);
InitializeSinReqMessage(&ApiReqMessage,sizeof(SIN_REQUEST_MESSAGE),LPC_NEW_MESSAGE,SIN_WAIT_SERVER);
Status = NtRequestWaitReplyPort(PortHandle,(PORT_MESSAGE*)&ApiReqMessage,(PORT_MESSAGE*)&ApiRecvMessage);
switch(ApiRecvMessage.Status)
{
case 0://do nothing wait for further instruction ...
{
Status = NtResetEvent(CommEvent,0);
goto WaitForServer;
}
case 1://execute Api Mapped into client process by server
{
if(ApiRecvMessage.StartAddress == 0)
{
goto WaitForServer;
}
else
{
if(ApiRecvMessage.Data != 0)
{
pClientApi = (SinSrvClientApiWithParameter)ApiRecvMessage.StartAddress;
pClientApi(ApiRecvMessage.Data);
goto WaitForServer;
}
else
{
ClientApi = (SinSrvClientApi)ApiRecvMessage.StartAddress;
ClientApi();
goto WaitForServer;
}
}
}
}
....