| /************************************************************** | 
 |  *  | 
 |  * 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 ) ); |