Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

192 lines
6.4 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
machine.cpp
Abstract:
This file implements the CreateMachApiThunk() function. This
function is responsible for emitting the individual API thunks
for the ppc architecture.
Author:
Wesley Witt (wesw) 28-June-1995
Environment:
User Mode
--*/
#include "apidllp.h"
#pragma hdrstop
//
// The following structure is used to save instructions in thunk.s by
// capturing global data in a single structure, thus avoiding TOC references.
//
extern "C" {
typedef
struct _APIDLL_PPC_DATA {
PVOID TlsGetValueEntry;
PVOID TlsGetValueToc;
PVOID TlsSetValueEntry;
PVOID TlsSetValueToc;
PVOID GetLastErrorEntry;
PVOID GetLastErrorToc;
PVOID SetLastErrorEntry;
PVOID SetLastErrorToc;
PVOID QueryPerformanceCounterEntry;
PVOID QueryPerformanceCounterToc;
PVOID ApiMonThunkCompleteEntry;
PVOID ApiTraceEnabled;
PVOID ApiCounter;
DWORD TlsReEnter;
DWORD TlsStack;
} APIDLL_PPC_DATA, *PAPIDLL_PPC_DATA;
APIDLL_PPC_DATA ApidllPpcData = {0};
}
PUCHAR
CreateMachApiThunk(
PULONG IatAddress,
PUCHAR Text,
PDLL_INFO DllInfo,
PAPI_INFO ApiInfo
)
/*++
Routine Description:
Emits the machine specific code for the API thunks.
Arguments:
IatAddress - Pointer to the IAT for this API
Text - Pointer to a buffer to place the generated code
DllInfo - Pointer to the DLL_INFO structure
ApiInfo - Pointer to the API_INFO structure
Return Value:
Pointer to the next byte to place more generated code.
--*/
{
PULONG Code = (PULONG)Text;
//
// If the ApidllPpcData structure hasn't been initialized yet, do so now.
//
if ( ApidllPpcData.TlsGetValueEntry == NULL ) {
ApidllPpcData.TlsGetValueEntry = ((PVOID *)pTlsGetValue)[0];
ApidllPpcData.TlsGetValueToc = ((PVOID *)pTlsGetValue)[1];
ApidllPpcData.TlsSetValueEntry = ((PVOID *)pTlsSetValue)[0];
ApidllPpcData.TlsSetValueToc = ((PVOID *)pTlsSetValue)[1];
ApidllPpcData.GetLastErrorEntry = ((PVOID *)pGetLastError)[0];
ApidllPpcData.GetLastErrorToc = ((PVOID *)pGetLastError)[1];
ApidllPpcData.SetLastErrorEntry = ((PVOID *)pSetLastError)[0];
ApidllPpcData.SetLastErrorToc = ((PVOID *)pSetLastError)[1];
ApidllPpcData.QueryPerformanceCounterEntry = ((PVOID *)pQueryPerformanceCounter)[0];
ApidllPpcData.QueryPerformanceCounterToc = ((PVOID *)pQueryPerformanceCounter)[1];
ApidllPpcData.ApiMonThunkCompleteEntry = ((PVOID *)ApiMonThunkComplete)[0];
ApidllPpcData.ApiTraceEnabled = ApiTraceEnabled;
ApidllPpcData.ApiCounter = ApiCounter;
ApidllPpcData.TlsReEnter = TlsReEnter;
ApidllPpcData.TlsStack = TlsStack;
}
//
// The entry in the IAT contains a pointer to the function descriptor
// for the target API.
//
PULONG TargetDescriptorAddress = *(PULONG *)IatAddress;
//
// The thunk needs to jump to ApiMonThunk using ApiMonThunk's function descriptor.
//
ULONG ApiMonThunkEntry = *(PULONG)ApiMonThunk;
ULONG ApiMonThunkToc = *((PULONG)ApiMonThunk + 1);
//
// If we've already created a thunk for this API, just point the IAT entry
// to the thunk's function descriptor.
//
if (ApiInfo->ThunkAddress) {
*IatAddress = ApiInfo->ThunkAddress;
return Text;
}
//
// Change the IAT entry to point to the function descriptor that we're about
// to create. Also, remember that we've thunked this API.
//
*IatAddress = (ULONG)Text;
ApiInfo->ThunkAddress = *IatAddress;
//
// Create a function descriptor for the thunk. The function starts right
// after the descriptor. Its TOC is APIDLL's TOC.
//
Code[0] = (ULONG)&Code[2];
Code++;
*Code++ = ApiMonThunkToc;
//
// Create the thunk. Branch via the CTR to ..ApiMonThunk. Note that we don't
// need to load r2 here because the caller will have loaded APIDLL's TOC via
// the function descriptor. The arguments to the thunk are as follows:
//
// r0 -- API flag
// r11 -- DllInfo
// r12 -- ApiInfo
//
*Code++ = 0x3c000000 | HIGH_ADDRX(ApiMonThunkEntry); // lis r0,0
*Code++ = 0x60000000 | LOW_ADDR(ApiMonThunkEntry); // ori r0,r0,0
*Code++ = 0x3d600000 | HIGH_ADDRX(DllInfo); // lis r11,0
*Code++ = 0x616b0000 | LOW_ADDR(DllInfo); // ori r11,r11,0
*Code++ = 0x3d800000 | HIGH_ADDRX(ApiInfo); // lis r12,0
*Code++ = 0x618c0000 | LOW_ADDR(ApiInfo); // ori r12,r12,0
*Code++ = 0x7c0903a6; // mtctr r0
//
if (_stricmp(DllInfo->Name,KERNEL32)==0) { //
if (strcmp((LPSTR)(ApiInfo->Name+(LPSTR)MemPtr),LOADLIBRARYA)==0) { //
*Code++ = 0x3c000001; // li r0,1
} else //
if (strcmp((LPSTR)(ApiInfo->Name+(LPSTR)MemPtr),LOADLIBRARYW)==0) { //
*Code++ = 0x3c000002; // li r0,2
} else //
if (strcmp((LPSTR)(ApiInfo->Name+(LPSTR)MemPtr),FREELIBRARY )==0) { //
*Code++ = 0x3c000003; // li r0,3
} else { //
*Code++ = 0x3c000000; // li r0,0
} //
} else { //
*Code++ = 0x3c000000; // li r0,0
} //
//
*Code++ = 0x4e800420; // bctr
//
// Return the next available thunk location.
//
return (PUCHAR)Code;
}