1*fc0bc008SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*fc0bc008SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*fc0bc008SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*fc0bc008SAndrew Rist  * distributed with this work for additional information
6*fc0bc008SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*fc0bc008SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*fc0bc008SAndrew Rist  * "License"); you may not use this file except in compliance
9*fc0bc008SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*fc0bc008SAndrew Rist  *
11*fc0bc008SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*fc0bc008SAndrew Rist  *
13*fc0bc008SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*fc0bc008SAndrew Rist  * software distributed under the License is distributed on an
15*fc0bc008SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*fc0bc008SAndrew Rist  * KIND, either express or implied.  See the License for the
17*fc0bc008SAndrew Rist  * specific language governing permissions and limitations
18*fc0bc008SAndrew Rist  * under the License.
19*fc0bc008SAndrew Rist  *
20*fc0bc008SAndrew Rist  *************************************************************/
21*fc0bc008SAndrew Rist 
22*fc0bc008SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "macros.h"
25cdf0e10cSrcweir #include "win95sys.h"
26cdf0e10cSrcweir #include <tlhelp32.h>
GetRealProcAddress(HMODULE hModule,LPCSTR lpProcName)27cdf0e10cSrcweir static FARPROC WINAPI GetRealProcAddress( HMODULE hModule, LPCSTR lpProcName )
28cdf0e10cSrcweir {
29cdf0e10cSrcweir     FARPROC	lpfn = GetProcAddress( hModule, lpProcName );
30cdf0e10cSrcweir 
31cdf0e10cSrcweir 	if ( lpfn )
32cdf0e10cSrcweir 	{
33cdf0e10cSrcweir 		if ( 0x68 == *(LPBYTE)lpfn )
34cdf0e10cSrcweir 		{
35cdf0e10cSrcweir 			/*
36cdf0e10cSrcweir 			82C9F460 68 36 49 F8 BF       push        0BFF84936h
37cdf0e10cSrcweir 			82C9F465 E9 41 62 2F 3D       jmp         BFF956AB
38cdf0e10cSrcweir 			*/
39cdf0e10cSrcweir 
40cdf0e10cSrcweir 			lpfn = (FARPROC)*(LPDWORD)((LPBYTE)lpfn + 1);
41cdf0e10cSrcweir 
42cdf0e10cSrcweir 			/*
43cdf0e10cSrcweir 			BFF956AB 9C                   pushfd
44cdf0e10cSrcweir 			BFF956AC FC                   cld
45cdf0e10cSrcweir 			BFF956AD 50                   push        eax
46cdf0e10cSrcweir 			BFF956AE 53                   push        ebx
47cdf0e10cSrcweir 			BFF956AF 52                   push        edx
48cdf0e10cSrcweir 			BFF956B0 64 8B 15 20 00 00 00 mov         edx,dword ptr fs:[20h]
49cdf0e10cSrcweir 			BFF956B7 0B D2                or          edx,edx
50cdf0e10cSrcweir 			BFF956B9 74 09                je          BFF956C4
51cdf0e10cSrcweir 			BFF956BB 8B 42 04             mov         eax,dword ptr [edx+4]
52cdf0e10cSrcweir 			BFF956BE 0B C0                or          eax,eax
53cdf0e10cSrcweir 			BFF956C0 74 07                je          BFF956C9
54cdf0e10cSrcweir 			BFF956C2 EB 42                jmp         BFF95706
55cdf0e10cSrcweir 			BFF956C4 5A                   pop         edx
56cdf0e10cSrcweir 			BFF956C5 5B                   pop         ebx
57cdf0e10cSrcweir 			BFF956C6 58                   pop         eax
58cdf0e10cSrcweir 			BFF956C7 9D                   popfd
59cdf0e10cSrcweir 			BFF956C8 C3                   ret
60cdf0e10cSrcweir 			*/
61cdf0e10cSrcweir 		}
62cdf0e10cSrcweir 	}
63cdf0e10cSrcweir 
64cdf0e10cSrcweir     return lpfn;
65cdf0e10cSrcweir }
66cdf0e10cSrcweir 
67cdf0e10cSrcweir 
68cdf0e10cSrcweir typedef DWORD (WINAPI OBFUSCATE)( DWORD dwPTID );
69cdf0e10cSrcweir typedef OBFUSCATE *LPOBFUSCATE;
70cdf0e10cSrcweir 
Obfuscate(DWORD dwPTID)71cdf0e10cSrcweir static DWORD WINAPI Obfuscate( DWORD dwPTID )
72cdf0e10cSrcweir {
73cdf0e10cSrcweir     static LPOBFUSCATE lpfnObfuscate = NULL;
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 	if ( !lpfnObfuscate )
76cdf0e10cSrcweir 	{
77cdf0e10cSrcweir 		LPBYTE lpCode = (LPBYTE)GetRealProcAddress( GetModuleHandleA("KERNEL32"), "GetCurrentThreadId" );
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 		if ( lpCode )
80cdf0e10cSrcweir 		{
81cdf0e10cSrcweir 			/*
82cdf0e10cSrcweir 			GetCurrentThreadId:
83cdf0e10cSrcweir 			lpCode + 00 BFF84936 A1 DC 9C FC BF       mov         eax,[BFFC9CDC]	; This is the real thread id
84cdf0e10cSrcweir 			lpcode + 05 BFF8493B FF 30                push        dword ptr [eax]
85cdf0e10cSrcweir 			lpCode + 07 BFF8493D E8 17 C5 FF FF       call        BFF80E59			; call Obfuscate function
86cdf0e10cSrcweir 			lpcode + 0C BFF84942 C3                   ret
87cdf0e10cSrcweir 			*/
88cdf0e10cSrcweir 
89cdf0e10cSrcweir 			DWORD	dwOffset = *(LPDWORD)(lpCode + 0x08);
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 			lpfnObfuscate = (LPOBFUSCATE)(lpCode + 0x0C + dwOffset);
92cdf0e10cSrcweir 			/*
93cdf0e10cSrcweir 			Obfuscate:
94cdf0e10cSrcweir 			BFF80E59 A1 CC 98 FC BF       mov         eax,[BFFC98CC]
95cdf0e10cSrcweir 			BFF80E5E 85 C0                test        eax,eax
96cdf0e10cSrcweir 			BFF80E60 75 04                jne         BFF80E66
97cdf0e10cSrcweir 			BFF80E62 33 C0                xor         eax,eax
98cdf0e10cSrcweir 			BFF80E64 EB 04                jmp         BFF80E6A
99cdf0e10cSrcweir 			BFF80E66 33 44 24 04          xor         eax,dword ptr [esp+4]
100cdf0e10cSrcweir 			BFF80E6A C2 04 00             ret         4
101cdf0e10cSrcweir 			*/
102cdf0e10cSrcweir 		}
103cdf0e10cSrcweir 
104cdf0e10cSrcweir 	}
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 	return lpfnObfuscate ? lpfnObfuscate( dwPTID ) : 0;
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 
GetProcessId_WINDOWS(HANDLE hProcess)110cdf0e10cSrcweir EXTERN_C DWORD WINAPI GetProcessId_WINDOWS( HANDLE hProcess )
111cdf0e10cSrcweir {
112cdf0e10cSrcweir 	if ( GetCurrentProcess() == hProcess )
113cdf0e10cSrcweir 		return GetCurrentProcessId();
114cdf0e10cSrcweir 
115cdf0e10cSrcweir 	DWORD	dwProcessId = 0;
116cdf0e10cSrcweir 	PPROCESS_DATABASE	pPDB = (PPROCESS_DATABASE)Obfuscate( GetCurrentProcessId() );
117cdf0e10cSrcweir 
118cdf0e10cSrcweir 	if ( pPDB && K32OBJ_PROCESS == pPDB->Type )
119cdf0e10cSrcweir 	{
120cdf0e10cSrcweir 		DWORD	dwHandleNumber = (DWORD)hProcess >> 2;
121cdf0e10cSrcweir 
122cdf0e10cSrcweir 		if ( 0 == ((DWORD)hProcess & 0x03) && dwHandleNumber < pPDB->pHandleTable->cEntries )
123cdf0e10cSrcweir 		{
124cdf0e10cSrcweir 			if (
125cdf0e10cSrcweir 				pPDB->pHandleTable->array[dwHandleNumber].pObject &&
126cdf0e10cSrcweir 				K32OBJ_PROCESS == pPDB->pHandleTable->array[dwHandleNumber].pObject->Type
127cdf0e10cSrcweir 				)
128cdf0e10cSrcweir 			dwProcessId = Obfuscate( (DWORD)pPDB->pHandleTable->array[dwHandleNumber].pObject );
129cdf0e10cSrcweir 		}
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 		SetLastError( ERROR_INVALID_HANDLE );
132cdf0e10cSrcweir 	}
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 	return dwProcessId;
135cdf0e10cSrcweir }
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 
GetProcessId_NT(HANDLE hProcess)138cdf0e10cSrcweir EXTERN_C DWORD WINAPI GetProcessId_NT( HANDLE hProcess )
139cdf0e10cSrcweir {
140cdf0e10cSrcweir 	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
141cdf0e10cSrcweir 	return 0;
142cdf0e10cSrcweir }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir 
ResolveThunk_GetProcessId(FARPROC * lppfn,LPCSTR lpLibFileName,LPCSTR lpFuncName)145cdf0e10cSrcweir EXTERN_C void WINAPI ResolveThunk_GetProcessId( FARPROC *lppfn, LPCSTR lpLibFileName, LPCSTR lpFuncName )
146cdf0e10cSrcweir {
147cdf0e10cSrcweir 	if ( (LONG)GetVersion() < 0 )
148cdf0e10cSrcweir 		*lppfn = (FARPROC)GetProcessId_WINDOWS;
149cdf0e10cSrcweir 	else
150cdf0e10cSrcweir 	{
151cdf0e10cSrcweir 		FARPROC	lpfnResult = GetProcAddress( LoadLibraryA( lpLibFileName ), lpFuncName );
152cdf0e10cSrcweir 		if ( !lpfnResult )
153cdf0e10cSrcweir 			lpfnResult = (FARPROC)GetProcessId_NT;
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 		*lppfn = lpfnResult;
156cdf0e10cSrcweir 	}
157cdf0e10cSrcweir }
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 
160cdf0e10cSrcweir DEFINE_CUSTOM_THUNK( kernel32, GetProcessId, DWORD, WINAPI, GetProcessId, ( HANDLE hProcess ) );
161