385 lines
8.6 KiB
C
385 lines
8.6 KiB
C
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include "apimon.h"
|
|
|
|
HANDLE ApiMonMutex;
|
|
PVOID MemPtr;
|
|
PDLL_INFO DllList;
|
|
|
|
LPDWORD ApiCounter;
|
|
LPDWORD ApiTraceEnabled;
|
|
LPDWORD ApiTimingEnabled;
|
|
LPDWORD FastCounterAvail;
|
|
LPDWORD ApiOffset;
|
|
LPDWORD ApiStrings;
|
|
LPDWORD ApiCount;
|
|
LPSTR TraceFileName;
|
|
|
|
|
|
PDLL_INFO
|
|
AddDllToList(
|
|
HANDLE hProcess,
|
|
ULONG DllAddr,
|
|
LPSTR DllName,
|
|
ULONG DllSize
|
|
);
|
|
|
|
ULONG
|
|
AddApisForDll(
|
|
HANDLE hProcess,
|
|
PDLL_INFO DllInfo
|
|
);
|
|
|
|
|
|
|
|
int _cdecl
|
|
main(
|
|
int argc,
|
|
char *argv[]
|
|
)
|
|
{
|
|
HANDLE hMap;
|
|
PDLL_INFO DllInfo;
|
|
|
|
|
|
hMap = CreateFileMapping(
|
|
(HANDLE)0xffffffff,
|
|
NULL,
|
|
PAGE_READWRITE | SEC_COMMIT,
|
|
0,
|
|
MAX_MEM_ALLOC,
|
|
"ApiWatch"
|
|
);
|
|
if (!hMap) {
|
|
return 1;
|
|
}
|
|
|
|
MemPtr = (PUCHAR)MapViewOfFile(
|
|
hMap,
|
|
FILE_MAP_WRITE,
|
|
0,
|
|
0,
|
|
0
|
|
);
|
|
if (!MemPtr) {
|
|
return 1;
|
|
}
|
|
ApiMonMutex = CreateMutex( NULL, FALSE, "ApiMonMutex" );
|
|
if (!ApiMonMutex) {
|
|
return FALSE;
|
|
}
|
|
|
|
ApiCounter = (LPDWORD)MemPtr + 0;
|
|
ApiTraceEnabled = (LPDWORD)MemPtr + 1;
|
|
ApiTimingEnabled = (LPDWORD)MemPtr + 2;
|
|
FastCounterAvail = (LPDWORD)MemPtr + 3;
|
|
ApiOffset = (LPDWORD)MemPtr + 4;
|
|
ApiStrings = (LPDWORD)MemPtr + 5;
|
|
ApiCount = (LPDWORD)MemPtr + 6;
|
|
TraceFileName = (LPSTR)((LPDWORD)MemPtr + 7);
|
|
DllList = (PDLL_INFO)((LPDWORD)MemPtr + 8 + MAX_PATH);
|
|
|
|
*ApiOffset = (MAX_DLLS * sizeof(DLL_INFO)) + ((ULONG)DllList - (ULONG)MemPtr);
|
|
*ApiStrings = (MAX_APIS * sizeof(API_INFO)) + *ApiOffset;
|
|
|
|
|
|
#if 0
|
|
DllInfo = AddDllToList( NULL,
|
|
HANDLE hProcess,
|
|
ULONG DllAddr,
|
|
LPSTR DllName,
|
|
ULONG DllSize
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
LoadLibrary( "apidll.dll" );
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL
|
|
ReadMemory(
|
|
HANDLE hProcess,
|
|
PVOID Address,
|
|
PVOID Buffer,
|
|
ULONG Length
|
|
)
|
|
{
|
|
CopyMemory( Buffer, Address, Length );
|
|
return TRUE;
|
|
}
|
|
|
|
PDLL_INFO
|
|
FindDllByAddress(
|
|
ULONG DllAddr
|
|
)
|
|
{
|
|
ULONG i;
|
|
for (i=0; i<MAX_DLLS; i++) {
|
|
if (DllList[i].BaseAddress == DllAddr) {
|
|
return &DllList[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
PDLL_INFO
|
|
FindDllByName(
|
|
LPSTR DllName
|
|
)
|
|
{
|
|
ULONG i;
|
|
for (i=0; i<MAX_DLLS; i++) {
|
|
if (DllList[i].Name[0] &&
|
|
_stricmp( DllList[i].Name, DllName ) == 0) {
|
|
return &DllList[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
PDLL_INFO
|
|
FindAvailDll(
|
|
VOID
|
|
)
|
|
{
|
|
ULONG i;
|
|
for (i=0; i<MAX_DLLS; i++) {
|
|
if (!DllList[i].BaseAddress) {
|
|
return &DllList[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
PDLL_INFO
|
|
AddDllToList(
|
|
HANDLE hProcess,
|
|
ULONG DllAddr,
|
|
LPSTR DllName,
|
|
ULONG DllSize
|
|
)
|
|
{
|
|
IMAGE_DOS_HEADER dh;
|
|
IMAGE_NT_HEADERS nh;
|
|
ULONG i;
|
|
PDLL_INFO DllInfo;
|
|
|
|
|
|
//
|
|
// first look to see if the dll is already in the list
|
|
//
|
|
DllInfo = FindDllByAddress( DllAddr );
|
|
|
|
if (!DllSize) {
|
|
//
|
|
// read the pe image headers to get the image size
|
|
//
|
|
if (!ReadMemory(
|
|
hProcess,
|
|
(PVOID) DllAddr,
|
|
&dh,
|
|
sizeof(dh)
|
|
)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (dh.e_magic == IMAGE_DOS_SIGNATURE) {
|
|
if (!ReadMemory(
|
|
hProcess,
|
|
(PVOID)(DllAddr + dh.e_lfanew),
|
|
&nh,
|
|
sizeof(nh)
|
|
)) {
|
|
return NULL;
|
|
}
|
|
DllSize = nh.OptionalHeader.SizeOfImage;
|
|
} else {
|
|
DllSize = 0;
|
|
}
|
|
}
|
|
|
|
DllInfo = FindAvailDll();
|
|
if (!DllInfo) {
|
|
return NULL;
|
|
}
|
|
|
|
DllInfo->Size = DllSize;
|
|
strncat( DllInfo->Name, DllName, MAX_NAME_SZ-1 );
|
|
DllInfo->BaseAddress = DllAddr;
|
|
DllInfo->InList = FALSE;
|
|
DllInfo->Enabled = TRUE;
|
|
|
|
return DllInfo;
|
|
}
|
|
|
|
ULONG
|
|
AddApisForDll(
|
|
HANDLE hProcess,
|
|
PDLL_INFO DllInfo
|
|
)
|
|
{
|
|
IMAGE_DOS_HEADER dh;
|
|
IMAGE_NT_HEADERS nh;
|
|
IMAGE_EXPORT_DIRECTORY expdir;
|
|
PULONG names = NULL;
|
|
PULONG addrs = NULL;
|
|
PUSHORT ordinals = NULL;
|
|
PUSHORT ordidx = NULL;
|
|
PAPI_INFO ApiInfo = NULL;
|
|
ULONG cnt = 0;
|
|
ULONG idx = 0;
|
|
ULONG i;
|
|
ULONG j;
|
|
LPSTR p;
|
|
|
|
|
|
if (*ApiCount == MAX_APIS) {
|
|
goto exit;
|
|
}
|
|
|
|
if (!ReadMemory(
|
|
hProcess,
|
|
(PVOID)DllInfo->BaseAddress,
|
|
&dh,
|
|
sizeof(dh)
|
|
)) {
|
|
goto exit;
|
|
}
|
|
|
|
if (dh.e_magic != IMAGE_DOS_SIGNATURE) {
|
|
goto exit;
|
|
}
|
|
|
|
if (!ReadMemory(
|
|
hProcess,
|
|
(PVOID)(DllInfo->BaseAddress + dh.e_lfanew),
|
|
&nh,
|
|
sizeof(nh)
|
|
)) {
|
|
goto exit;
|
|
}
|
|
|
|
if (!nh.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) {
|
|
goto exit;
|
|
}
|
|
|
|
if (!ReadMemory(
|
|
hProcess,
|
|
(PVOID)(DllInfo->BaseAddress +
|
|
nh.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress),
|
|
&expdir,
|
|
sizeof(expdir)
|
|
)) {
|
|
goto exit;
|
|
}
|
|
|
|
names = (PULONG) LocalAlloc( LPTR, expdir.NumberOfNames * sizeof(ULONG) );
|
|
addrs = (PULONG) LocalAlloc( LPTR, expdir.NumberOfFunctions * sizeof(ULONG) );
|
|
ordinals = (PUSHORT) LocalAlloc( LPTR, expdir.NumberOfNames * sizeof(USHORT) );
|
|
ordidx = (PUSHORT) LocalAlloc( LPTR, expdir.NumberOfFunctions * sizeof(USHORT) );
|
|
|
|
if ((!names) || (!addrs) || (!ordinals) || (!ordidx)) {
|
|
goto exit;
|
|
}
|
|
|
|
if (!ReadMemory(
|
|
hProcess,
|
|
(PVOID)(DllInfo->BaseAddress + (ULONG)expdir.AddressOfNames),
|
|
names,
|
|
expdir.NumberOfNames * sizeof(ULONG)
|
|
)) {
|
|
goto exit;
|
|
}
|
|
|
|
if (!ReadMemory(
|
|
hProcess,
|
|
(PVOID)(DllInfo->BaseAddress + (ULONG)expdir.AddressOfFunctions),
|
|
addrs,
|
|
expdir.NumberOfFunctions * sizeof(ULONG)
|
|
)) {
|
|
goto exit;
|
|
}
|
|
|
|
if (!ReadMemory(
|
|
hProcess,
|
|
(PVOID)(DllInfo->BaseAddress + (ULONG)expdir.AddressOfNameOrdinals),
|
|
ordinals,
|
|
expdir.NumberOfNames * sizeof(USHORT)
|
|
)) {
|
|
goto exit;
|
|
}
|
|
|
|
DllInfo->ApiCount = expdir.NumberOfFunctions;
|
|
DllInfo->ApiOffset = *ApiOffset;
|
|
*ApiOffset += (DllInfo->ApiCount * sizeof(API_INFO));
|
|
ApiInfo = (PAPI_INFO)(DllInfo->ApiOffset + (ULONG)DllList);
|
|
|
|
if (*ApiCount < MAX_APIS) {
|
|
for (i=0; i<expdir.NumberOfNames; i++) {
|
|
idx = ordinals[i];
|
|
ordidx[idx] = TRUE;
|
|
ApiInfo[i].Count = 0;
|
|
ApiInfo[i].ThunkAddress = 0;
|
|
ApiInfo[i].Address = addrs[idx] + DllInfo->BaseAddress;
|
|
j = 0;
|
|
p = (LPSTR)((LPSTR)MemPtr+*ApiStrings);
|
|
do {
|
|
ReadMemory(
|
|
hProcess,
|
|
(PVOID)(DllInfo->BaseAddress + names[i] + j),
|
|
&p[j],
|
|
1
|
|
);
|
|
j += 1;
|
|
} while(p[j-1]);
|
|
ApiInfo[i].Name = *ApiStrings;
|
|
*ApiStrings += (strlen((LPSTR)((LPSTR)MemPtr+*ApiStrings)) + 1);
|
|
*ApiCount += 1;
|
|
if (*ApiCount == MAX_APIS) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (*ApiCount < MAX_APIS) {
|
|
for (i=0,idx=expdir.NumberOfNames; i<expdir.NumberOfFunctions; i++) {
|
|
if (!ordidx[i]) {
|
|
ApiInfo[idx].Count = 0;
|
|
ApiInfo[idx].ThunkAddress = 0;
|
|
ApiInfo[idx].Address = addrs[i] + DllInfo->BaseAddress;
|
|
sprintf(
|
|
(LPSTR)((LPSTR)MemPtr+*ApiStrings),
|
|
"Ordinal%d",
|
|
i
|
|
);
|
|
ApiInfo[idx].Name = *ApiStrings;
|
|
*ApiStrings += (strlen((LPSTR)((LPSTR)MemPtr+*ApiStrings)) + 1);
|
|
*ApiCount += 1;
|
|
if (*ApiCount == MAX_APIS) {
|
|
break;
|
|
}
|
|
idx += 1;
|
|
}
|
|
}
|
|
}
|
|
cnt = DllInfo->ApiCount;
|
|
|
|
exit:
|
|
LocalFree( names );
|
|
LocalFree( addrs );
|
|
LocalFree( ordinals );
|
|
LocalFree( ordidx );
|
|
|
|
return cnt;
|
|
}
|