/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#include "macros.h"
#include "win95sys.h"
#include <tlhelp32.h>
static FARPROC WINAPI GetRealProcAddress( HMODULE hModule, LPCSTR lpProcName )
{
    FARPROC	lpfn = GetProcAddress( hModule, lpProcName );

	if ( lpfn )
	{
		if ( 0x68 == *(LPBYTE)lpfn )
		{
			/*
			82C9F460 68 36 49 F8 BF       push        0BFF84936h
			82C9F465 E9 41 62 2F 3D       jmp         BFF956AB
			*/

			lpfn = (FARPROC)*(LPDWORD)((LPBYTE)lpfn + 1);

			/*
			BFF956AB 9C                   pushfd
			BFF956AC FC                   cld
			BFF956AD 50                   push        eax
			BFF956AE 53                   push        ebx
			BFF956AF 52                   push        edx
			BFF956B0 64 8B 15 20 00 00 00 mov         edx,dword ptr fs:[20h]
			BFF956B7 0B D2                or          edx,edx
			BFF956B9 74 09                je          BFF956C4
			BFF956BB 8B 42 04             mov         eax,dword ptr [edx+4]
			BFF956BE 0B C0                or          eax,eax
			BFF956C0 74 07                je          BFF956C9
			BFF956C2 EB 42                jmp         BFF95706
			BFF956C4 5A                   pop         edx
			BFF956C5 5B                   pop         ebx
			BFF956C6 58                   pop         eax
			BFF956C7 9D                   popfd
			BFF956C8 C3                   ret
			*/		
		}
	}

    return lpfn;
}


typedef DWORD (WINAPI OBFUSCATE)( DWORD dwPTID );
typedef OBFUSCATE *LPOBFUSCATE;

static DWORD WINAPI Obfuscate( DWORD dwPTID )
{
    static LPOBFUSCATE lpfnObfuscate = NULL;

	if ( !lpfnObfuscate )
	{
		LPBYTE lpCode = (LPBYTE)GetRealProcAddress( GetModuleHandleA("KERNEL32"), "GetCurrentThreadId" );

		if ( lpCode )
		{
			/* 
			GetCurrentThreadId:
			lpCode + 00 BFF84936 A1 DC 9C FC BF       mov         eax,[BFFC9CDC]	; This is the real thread id
			lpcode + 05 BFF8493B FF 30                push        dword ptr [eax]
			lpCode + 07 BFF8493D E8 17 C5 FF FF       call        BFF80E59			; call Obfuscate function
			lpcode + 0C BFF84942 C3                   ret
			*/

			DWORD	dwOffset = *(LPDWORD)(lpCode + 0x08);

			lpfnObfuscate = (LPOBFUSCATE)(lpCode + 0x0C + dwOffset);
			/*
			Obfuscate:
			BFF80E59 A1 CC 98 FC BF       mov         eax,[BFFC98CC]
			BFF80E5E 85 C0                test        eax,eax
			BFF80E60 75 04                jne         BFF80E66
			BFF80E62 33 C0                xor         eax,eax
			BFF80E64 EB 04                jmp         BFF80E6A
			BFF80E66 33 44 24 04          xor         eax,dword ptr [esp+4]
			BFF80E6A C2 04 00             ret         4
			*/
		}
		
	}

	return lpfnObfuscate ? lpfnObfuscate( dwPTID ) : 0;
}


EXTERN_C DWORD WINAPI GetProcessId_WINDOWS( HANDLE hProcess )
{
	if ( GetCurrentProcess() == hProcess )
		return GetCurrentProcessId();

	DWORD	dwProcessId = 0;
	PPROCESS_DATABASE	pPDB = (PPROCESS_DATABASE)Obfuscate( GetCurrentProcessId() );

	if ( pPDB && K32OBJ_PROCESS == pPDB->Type )
	{
		DWORD	dwHandleNumber = (DWORD)hProcess >> 2;

		if ( 0 == ((DWORD)hProcess & 0x03) && dwHandleNumber < pPDB->pHandleTable->cEntries )
		{
			if ( 
				pPDB->pHandleTable->array[dwHandleNumber].pObject && 
				K32OBJ_PROCESS == pPDB->pHandleTable->array[dwHandleNumber].pObject->Type 
				)
			dwProcessId = Obfuscate( (DWORD)pPDB->pHandleTable->array[dwHandleNumber].pObject );
		}

		SetLastError( ERROR_INVALID_HANDLE );
	}
	
	return dwProcessId;
}


EXTERN_C DWORD WINAPI GetProcessId_NT( HANDLE hProcess )
{
	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
	return 0;
}


EXTERN_C void WINAPI ResolveThunk_GetProcessId( FARPROC *lppfn, LPCSTR lpLibFileName, LPCSTR lpFuncName )
{
	if ( (LONG)GetVersion() < 0 )
		*lppfn = (FARPROC)GetProcessId_WINDOWS;
	else
	{
		FARPROC	lpfnResult = GetProcAddress( LoadLibraryA( lpLibFileName ), lpFuncName );
		if ( !lpfnResult )
			lpfnResult = (FARPROC)GetProcessId_NT;

		*lppfn = lpfnResult;
	}
}


DEFINE_CUSTOM_THUNK( kernel32, GetProcessId, DWORD, WINAPI, GetProcessId, ( HANDLE hProcess ) );
