📄 krnldataclient.cpp
字号:
// KrnlDataClient.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
const char DEVICE_NAME[] = "\\\\.\\dvKrnlDataDevice";
const int LOG_BIN_NUM = 16;
char *GetFileName(char *szPath)
{
if(strchr(szPath, '\\') == NULL)
{
return szPath;
}
char *szTemp = szPath;
char *szRet;
while( szTemp != NULL )
{
szRet = szTemp + 1;
szTemp = strchr(szRet, '\\');
}
return szRet;
}
void PrintUsage(char *szExe)
{
printf(
"=========================Usage=========================\n"
"%s <option> <address> <number>\n"
"option: \t-b\tin BYTE order\n"
" \t-s\tin SHORT order\n"
" \t-d\tin DWORD order\n"
"address: \tthe address u want to get data in hex\n"
"number: \thow many number u want to get according to option\n"
"=======================================================\n",
GetFileName(szExe));
}
bool IsValidAscii(char s)
{
if((BYTE)s < 33 || (BYTE)s > 128)
{
return false;
}
return true;
}
void PrintDataInbyte(BYTE *pData, DWORD dwBase, DWORD dwLen)
{
int nTime = dwLen / LOG_BIN_NUM;
CHAR cAscii[LOG_BIN_NUM + 1] = {0};
int i = 0;
int j = 0;
int n = 0;
int temp = 0;
for(n = 0; n < nTime; n++)
{
printf( "[%08X]: ", LOG_BIN_NUM * n + dwBase);
for(i = (LOG_BIN_NUM * n); i < LOG_BIN_NUM * (n + 1); i++)
{
printf( "%.2X ", pData[i] );
}
memcpy(cAscii, &pData[LOG_BIN_NUM * n], LOG_BIN_NUM);
for(j = 0; j < LOG_BIN_NUM; j++)
{
cAscii[j] = (IsValidAscii(cAscii[j])?cAscii[j]:0x20);
}
printf(" %s\n", cAscii);
}
temp = i;
memset(cAscii, 0, LOG_BIN_NUM + 1);
if( i < dwLen )
{
printf("[%08X]: ", LOG_BIN_NUM * n + dwBase);
for(; i < dwLen; i++)
{
printf("%.2X ", pData[i] );
}
for(; i < LOG_BIN_NUM * (n + 1); i++)
{
printf(" ");
}
memcpy(cAscii, &pData[temp], dwLen - temp);
for(j = 0; j < dwLen - temp; j++)
{
cAscii[j] = (IsValidAscii(cAscii[j])?cAscii[j]:0x20);
}
printf(" %s\n", cAscii);
}
printf("\n");
}
void PrintDataIndword(BYTE *pData, DWORD dwBase, DWORD dwLen)
{
int nTime = dwLen / LOG_BIN_NUM;
int nLineNum = LOG_BIN_NUM / sizeof(DWORD);
int i = 0;
int n = 0;
int temp = 0;
DWORD *pdwData = (DWORD *)pData;
for(n = 0; n < nTime; n++)
{
printf( "[%08X]: ", LOG_BIN_NUM * n + dwBase);
for(i = (nLineNum * n); i < nLineNum * (n + 1); i++)
{
printf( "%08X ", pdwData[i] );
}
printf("\n");
}
temp = i;
if( i < (dwLen / sizeof(DWORD)) )
{
printf("[%08X]: ", LOG_BIN_NUM * n + dwBase);
for(; i < (dwLen / sizeof(DWORD)); i++)
{
printf( "%08X ", pdwData[i] );
}
printf("\n");
}
printf("\n");
}
void PrintMemData(int nType, BYTE *pData, DWORD dwBase, DWORD dwLen)
{
switch(nType)
{
case 1: //byte
PrintDataInbyte(pData, dwBase, dwLen);
break;
case 2: //short
case 3: //dowrd
PrintDataIndword(pData, dwBase, dwLen);
break;
}
}
void PrintIDTData(BYTE *pData, DWORD dwLen)
{
int n = 0;
PIDTR pIdt = NULL;
PIDT_ENTRY pIdtEntry = NULL;
pIdt = (PIDTR)pData;
printf("IDTBase: %08X IDTLimit: %X\n", pIdt->IDTBase, pIdt->IDTLimit);
if((dwLen - sizeof(IDTR)) % sizeof(IDT_ENTRY) != 0)
{
printf("wrong len\n");
return;
}
n = (dwLen - sizeof(IDTR)) / sizeof(IDT_ENTRY);
pIdtEntry = (PIDT_ENTRY)(pData + sizeof(IDTR));
printf("Number Address Selector\n");
for(int i = 0; i < n; i++)
{
DWORD dwOffset = (DWORD)(pIdtEntry->OffsetLow) | ((DWORD)(pIdtEntry->OffsetHigh) << 16);
printf("%03X %08X %08X\n", i, dwOffset, pIdtEntry->Selector);
}
}
void PrintSSTData(BYTE *pData, DWORD dwLen)
{
PSYSTEM_SERVICE_TABLE pSST = NULL;
DWORD *pServiceEntry = NULL;
BYTE *pArgument = NULL;
pSST = (PSYSTEM_SERVICE_TABLE)pData;
printf("ServiceTable: %08X ArgumentTable: %08X Limit: %X\n",
pSST->ServiceTable,
pSST->ArgumentTable,
pSST->ServiceLimit);
if(dwLen < sizeof(SYSTEM_SERVICE_TABLE) + pSST->ServiceLimit * (sizeof(DWORD) + 1))
{
printf("wrong len\n");
return;
}
pServiceEntry = (DWORD *)(pData + sizeof(SYSTEM_SERVICE_TABLE));
pArgument = pData + sizeof(SYSTEM_SERVICE_TABLE) + pSST->ServiceLimit * sizeof(DWORD);
printf("Number Address Argument\n");
for(int i = 0; i < pSST->ServiceLimit; i++)
{
printf("%03X %08X %X\n", i, pServiceEntry[i], pArgument[i]);
}
}
int main(int argc, char* argv[])
{
BYTE temp[6];
__asm
{
sidt temp
}
printf("idt base: %08x limit: %X\n", *(DWORD *)&temp[2], *(SHORT *)temp);
if(argc == 1)
{
PrintUsage(argv[0]);
return 0;
}
//打开设备
HANDLE hDevice = CreateFile(
DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
printf("Error CreateFile:%08X\n", GetLastError());
return 0;
}
//隐藏指定ID的进程
if(strcmp(argv[1], "-hide") == 0)
{
if(argc != 3)
{
PrintUsage(argv[0]);
goto out;
}
DWORD dwPID = strtoul(argv[2], NULL, 10);
if(dwPID == 0)
{
PrintUsage(argv[0]);
goto out;
}
DWORD dwWritten = 0;
if( !DeviceIoControl(
hDevice,
KRNLDATA_IO_HIDE_PROC,
&dwPID,
sizeof(DWORD),
NULL,
0,
&dwWritten,
NULL))
{
printf("Error DeviceIoControl:%08X\n", GetLastError());
}
}
//停止隐藏进城
if(strcmp(argv[1], "-unhide") == 0)
{
DWORD dwWritten;
if( !DeviceIoControl(
hDevice,
KRNLDATA_IO_STOP_HIDE,
NULL,
0,
NULL,
0,
&dwWritten,
NULL))
{
printf("Error DeviceIoControl:%08X\n", GetLastError());
}
}
//获取线性地址对应的物理地址
if(strcmp(argv[1], "-physical") == 0)
{
if(argc != 3)
{
PrintUsage(argv[0]);
goto out;
}
DWORD dwAddress = strtoul(argv[2], NULL, 16);
if(dwAddress == 0)
{
PrintUsage(argv[0]);
goto out;
}
DWORD dwWritten = 0;
ULARGE_INTEGER PhysicalAddr;
if( !DeviceIoControl(
hDevice,
KRNLDATA_IO_PHYSICAL,
&dwAddress,
sizeof(DWORD),
&PhysicalAddr,
sizeof(ULARGE_INTEGER),
&dwWritten,
NULL))
{
printf("Error DeviceIoControl:%08X\n", GetLastError());
}
else
{
printf("Line Addr: %08X Physical Addr: %08X-%08X\n",
dwAddress,
PhysicalAddr.u.HighPart,
PhysicalAddr.u.LowPart);
}
}
//读取中断表请求
if(strcmp(argv[1], "-idt") == 0)
{
DWORD dwWritten = 0;
DWORD dwLen = sizeof(IDTR) + sizeof(IDT_ENTRY) * 0xFF;
BYTE *pDataBuf = new BYTE[dwLen];
if( !DeviceIoControl(
hDevice,
KRNLDATA_IO_IDT,
NULL,
0,
pDataBuf,
dwLen,
&dwWritten,
NULL))
{
printf("Error DeviceIoControl:%08X\n", GetLastError());
}
else
{
PrintIDTData(pDataBuf, dwWritten);
}
delete []pDataBuf;
}
//读取服务表请求
if(strcmp(argv[1], "-sst") == 0)
{
DWORD dwWritten = 0;
DWORD dwLen = sizeof(SYSTEM_SERVICE_TABLE) + 5 * 2000;
BYTE *pDataBuf = new BYTE[dwLen];
if( !DeviceIoControl(
hDevice,
KRNLDATA_IO_SST,
NULL,
0,
pDataBuf,
dwLen,
&dwWritten,
NULL))
{
printf("Error DeviceIoControl:%08X\n", GetLastError());
}
else
{
PrintSSTData(pDataBuf, dwWritten);
}
delete []pDataBuf;
}
//读取内存请求
if(strcmp(argv[1], "-memory") == 0)
{
if(argc != 5)
{
PrintUsage(argv[0]);
goto out;
}
DWORD dwAddress = strtoul(argv[3], NULL, 16);
if(dwAddress == 0)
{
PrintUsage(argv[0]);
goto out;
}
DWORD dwLen = strtoul(argv[4], NULL, 10);
if(dwLen == 0)
{
PrintUsage(argv[0]);
goto out;
}
int nPrintType = 0;
if( strcmp(argv[2], "-b") == 0)
{
nPrintType = 1; //byte
}
if(strcmp(argv[2], "-s") == 0)
{
nPrintType = 2; //short
dwLen *= 2;
}
if(strcmp(argv[2], "-d") == 0)
{
nPrintType = 3; //dword
dwLen *= 4;
}
if(nPrintType == 0)
{
PrintUsage(argv[0]);
goto out;
}
//读取内存制定位置的数据
DVKRNLDATA_MEM_REQUEST MemReq;
MemReq.pAddress = (LPVOID)dwAddress;
MemReq.dwRequestLen = dwLen;
BYTE *pDataBuf = new BYTE[dwLen];
DWORD dwWritten = 0;
if(dwAddress < 0x80000000)
{
//非内核区域
__try
{
memcpy(pDataBuf, (LPVOID)dwAddress, dwLen);
PrintMemData(nPrintType, pDataBuf, dwAddress, dwLen);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Invalid Memory Address!\n");
}
}
else
{
//内核区域通过驱动来获取
if( !DeviceIoControl(
hDevice,
KRNLDATA_IO_READ_MEM,
(LPVOID)&MemReq,
sizeof(MemReq),
pDataBuf,
dwLen,
&dwWritten,
NULL))
{
printf("Error DeviceIoControl:%08X\n", GetLastError());
}
else
{
PrintMemData(nPrintType, pDataBuf, dwAddress, dwWritten);
}
}
delete []pDataBuf;
}
out:
CloseHandle(hDevice);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -