编程获取当前Windows平台的System Service列表
2006-09-27 09:11
274 查看
通常我们都是通过反汇编或者静态数组映射的方式获取构建System Service Id到System Service的映射的,这种方式依赖于Windows的版本。为了克服这个不足,本文介绍了一种编程动态获取当前Windows平台的System Service列表的方法。
代码如下:
bool IsSystemService (LPCTSTR lpcszFunctionName, PBYTE pFunction, ULONG &nServiceId)
{
if (!lpcszFunctionName || !pFunction)
return false;
if ((lpcszFunctionName [0] != 'N')|| (lpcszFunctionName [1] != 't'))
return false;
//
// 77F5B438 B8 00000000 MOV EAX, _FUNCTION_ID_
// 77F5B43D BA 0003FE7F MOV EDX,7FFE0300
// 77F5B442 FF12 CALL EDX
// 77F5B444 C2 1800 RETN XX
//
//
// mov eax
//
if ( *pFunction != 0xB8 )
{
return false;
}
//
// since the address of the function which actually makes the call6 (SYSCALL) may change, we
// just check for mov edx
//
if ( *(pFunction + 5) != 0xBA )
{
return false;
}
//
// call edx
//
if ( *(PWORD)(pFunction + 10) != 0x12FF )
{
return false;
}
//
// retn
//
if ( *(pFunction + 12) != 0xC2 )
{
return false;
}
nServiceId = *(PDWORD)(pFunction + 1);
return true;
}
bool GetSystemService ()
{
//get the function's address
HMODULE hMod = GetModuleHandle ("ntdll.dll");
if (!hMod)
return false;
IMAGE_DOS_HEADER* dosheader;
IMAGE_OPTIONAL_HEADER* opthdr;
IMAGE_EXPORT_DIRECTORY* pExportTable;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
ULONG Base, x, functionAddress;
char* functionName;
PVOID BaseAddress = NULL;
SIZE_T size=0;
dosheader = (IMAGE_DOS_HEADER *)hMod;
opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24);
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*) hMod + opthdr->DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress);
// now we can get the exported functions, but note we convert from RVA to address
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfFunctions);
arrayOfFunctionNames = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfNames);
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)hMod + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
ULONG nServiceId = 0;
for(x = 0; x < pExportTable->NumberOfFunctions; x++)
{
functionName = (char*)( (BYTE*)hMod + arrayOfFunctionNames[x]);
functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1; // always need to add base, -1 as array counts from 0
// this is the funny bit. you would expect the function pointer to simply be arrayOfFunctionAddresses[x]...
// oh no... thats too simple. it is actually arrayOfFunctionAddresses[functionOrdinal]!!
functionAddress = (DWORD)( (BYTE*)hMod + arrayOfFunctionAddresses[functionOrdinal]);
if (IsSystemService (functionName, (PBYTE)functionAddress, nServiceId))
{
printf ("0x%08x %s 0x%08x/n",
nServiceId,
functionName,
functionAddress);
}
}
FreeLibrary (hMod);
return TRUE;
}
代码如下:
bool IsSystemService (LPCTSTR lpcszFunctionName, PBYTE pFunction, ULONG &nServiceId)
{
if (!lpcszFunctionName || !pFunction)
return false;
if ((lpcszFunctionName [0] != 'N')|| (lpcszFunctionName [1] != 't'))
return false;
//
// 77F5B438 B8 00000000 MOV EAX, _FUNCTION_ID_
// 77F5B43D BA 0003FE7F MOV EDX,7FFE0300
// 77F5B442 FF12 CALL EDX
// 77F5B444 C2 1800 RETN XX
//
//
// mov eax
//
if ( *pFunction != 0xB8 )
{
return false;
}
//
// since the address of the function which actually makes the call6 (SYSCALL) may change, we
// just check for mov edx
//
if ( *(pFunction + 5) != 0xBA )
{
return false;
}
//
// call edx
//
if ( *(PWORD)(pFunction + 10) != 0x12FF )
{
return false;
}
//
// retn
//
if ( *(pFunction + 12) != 0xC2 )
{
return false;
}
nServiceId = *(PDWORD)(pFunction + 1);
return true;
}
bool GetSystemService ()
{
//get the function's address
HMODULE hMod = GetModuleHandle ("ntdll.dll");
if (!hMod)
return false;
IMAGE_DOS_HEADER* dosheader;
IMAGE_OPTIONAL_HEADER* opthdr;
IMAGE_EXPORT_DIRECTORY* pExportTable;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
ULONG Base, x, functionAddress;
char* functionName;
PVOID BaseAddress = NULL;
SIZE_T size=0;
dosheader = (IMAGE_DOS_HEADER *)hMod;
opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24);
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*) hMod + opthdr->DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress);
// now we can get the exported functions, but note we convert from RVA to address
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfFunctions);
arrayOfFunctionNames = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfNames);
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)hMod + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
ULONG nServiceId = 0;
for(x = 0; x < pExportTable->NumberOfFunctions; x++)
{
functionName = (char*)( (BYTE*)hMod + arrayOfFunctionNames[x]);
functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1; // always need to add base, -1 as array counts from 0
// this is the funny bit. you would expect the function pointer to simply be arrayOfFunctionAddresses[x]...
// oh no... thats too simple. it is actually arrayOfFunctionAddresses[functionOrdinal]!!
functionAddress = (DWORD)( (BYTE*)hMod + arrayOfFunctionAddresses[functionOrdinal]);
if (IsSystemService (functionName, (PBYTE)functionAddress, nServiceId))
{
printf ("0x%08x %s 0x%08x/n",
nServiceId,
functionName,
functionAddress);
}
}
FreeLibrary (hMod);
return TRUE;
}
相关文章推荐
- 编程获取当前Windows平台的System Service列表
- windows核心编程-获取进程当前目录
- 获取当前运行平台
- windows平台下通过注册表获取特定后缀名的默认图标
- 如何在Windows平台下可以方便获取到android的源码?
- Windows获取系统当前时区的两种方法
- Windows 驱动:获取系统当前时间,生成格式字符串
- 基于Visual C++之Windows核心编程代码分析(4)获取操作系统信息
- jsp获取当前目录下的文件和目录,获取windows盘符
- 基于visual c++之windows核心编程代码分析(21)获取和设置环境变量
- VC++ Windows平台字符透明编程大总结
- Windows编程 - 获取运行程序的基地址
- 在苹果iOS平台中获取当前程序进程的进程名等信息
- windows的磁盘操作之七——获取当前所有的物理磁盘号
- Socket原理与编程基础 Windows平台
- windows核心编程-获取进程中堆的分配情况
- Windows编程学习札记:获取设备环境句柄
- (C#)Windows Shell 编程系列5 - 获取图标
- centos shell编程5 LANMP一键安装脚本 lamp sed lnmp 变量和字符串比较不能用-eq cat > /usr/local/apache2/htdocs/index.php <<EOF重定向 shell的变量和函数命名不能有横杠 平台可以用arch命令,获取是i686还是x86_64 curl 下载 第三十九节课
- 同样指令bmp.LockBits不同平台(Windows/WinCE)获取位图的数据不同