-
-
[旧帖] [求助]编译驱动提示这样的错误怎么办? 0.00雪花
-
发表于: 2012-4-16 19:48 1190
-
编译驱动提示这样的错误怎么办?
编译环境 VS2008 + WDK
error PRJ0002 : 错误的结果 255 (从“C:\WINDOWS\System32\cmd.exe”返回)
附上源代码:
//头文件ProtProtect.h源代码在下面附上
#include "ProtProtect.h"
PZW_OPEN_PROCESS g_OldZwOpenProcess;
ULONG g_ulProcId = -1;
ULONG g_blEnableProt = FALSE;
NTSTATUS NewZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
// 如果打开的进程是我们要保护的进程,就返回STATUS_ACCESS_DENIED
// 进程用户打开
if((g_blEnableProt==TRUE) && (ClientId->UniqueProcess==g_ulProcId))
{
DbgPrint("保护进程 g_ulProcId:%ld\n",g_ulProcId);
return STATUS_ACCESS_DENIED;
}
// 如果不是我们要保护的进程,就交给原例程处理
return g_OldZwOpenProcess(
ProcessHandle,
DesiredAccess,
ObjectAttributes,
ClientId
);
}
NTSTATUS OnIrpDefaultRoutine(
IN PDEVICE_OBJECT pstDeviceObject,
IN PIRP pstIrp
)
{
pstIrp->IoStatus.Status = STATUS_SUCCESS;
pstIrp->IoStatus.Information = 0;
IoCompleteRequest(pstIrp,IO_NO_INCREMENT);
}
VOID DriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
UNICODE_STRING usSymbolLink = RTL_CONSTANT_STRING(DOS_DEVICE_NAME);
PDEVICE_OBJECT pstDevObj = NULL;
// 删除设备连接符
IoDeleteSymbolicLink(&usSymbolLink);
if(DriverObject)
{
// 删除驱动创建的所有设备
pstDevObj=DriverObject->DeviceObject;
while(pstDevObj)
{
IoDeleteDevice(pstDevObj);
pstDevObj = pstDevObj->NextDevice;
}
}
DbgPrint("now , unhook the NtOpenProcess routine !\n");
DisableMemProtect();
InterlockedExchangePointer(&(SYSTEMSERVICE(ZwOpenProcess)),g_OldZwOpenProcess);
RecoverMemProtect();
DbgPrint("the driver has been unloaded !\n");
}
NTSTATUS OnIprDeviceControlRoutine(
IN PDEVICE_OBJECT pstDeviceObject,
IN PIRP pstIrp
)
{
NTSTATUS ntStatus;
ULONG ulCtlCode = 0;
PIO_STACK_LOCATION pstStackLocation = NULL;
PPROC_PROTECT_DEVICEEXTENSION pstDevExtension = NULL;
pstStackLocation = IoGetCurrentIrpStackLocation(pstIrp);
pstDevExtension = \
(PPROC_PROTECT_DEVICEEXTENSION)pstDeviceObject->DeviceExtension;
pstIrp->IoStatus.Information = 0;
/*
* IRP_MJ_DEVICE_CONTROL的分发处理例程。。。
*/
if(pstStackLocation->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
switch(pstStackLocation->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_CHANGLE_PROCESS:
{
//g_ulProcId = *(ULONG *)pstIrp->AssociatedIrp.SystemBuffer;
pstDevExtension->ulProcId = *(ULONG *)pstIrp->AssociatedIrp.SystemBuffer;
InterlockedExchange(&g_ulProcId,pstDevExtension->ulProcId);
/*
DbgPrint("===========================\n");
DbgPrint("IOCTL_PROTECT_CONTROL 被调用,通讯成功!\n");
DbgPrint("输入缓冲区大小: %d\n",\
pstStackLocation->Parameters.DeviceIoControl.InputBufferLength);
DbgPrint("输出缓冲区大小: %d\n",\
pstStackLocation->Parameters.DeviceIoControl.OutputBufferLength);
DbgPrint("输入缓冲区地址: %ld\n",\
pstStackLocation->Parameters.DeviceIoControl.Type3InputBuffer);
DbgPrint("当前保护进程ID: %ld\n",pstDevExtension->ulProcId);
DbgPrint("===========================\n");
//strcpy(Irp->UserBuffer,"OK!\n");
*/
ntStatus = STATUS_SUCCESS;
break;
}
case IOCTL_ENABLE_PROTECT:
{
pstDevExtension->blEnableProt = TRUE;
pstDevExtension->ulProcId = *(ULONG *)pstIrp->AssociatedIrp.SystemBuffer;
InterlockedExchange(&g_blEnableProt,pstDevExtension->blEnableProt);
InterlockedExchange(&g_ulProcId,pstDevExtension->ulProcId);
ntStatus = STATUS_SUCCESS;
break;
}
case IOCTL_DISABLE_PROTECT:
{
pstDevExtension->blEnableProt = FALSE;
ntStatus = STATUS_SUCCESS;
break;
}
default:
{
DbgPrint("it should be run here , something must be wrong !\n");
ntStatus = STATUS_ACCESS_DENIED;
break;
}
}
}
else
{
DbgPrint("it should be run here , something must be wrong !\n");
ntStatus = STATUS_ACCESS_DENIED;
}
pstIrp->IoStatus.Status = ntStatus;
IoCompleteRequest(pstIrp,IO_NO_INCREMENT);
return ntStatus;
}
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT pstDriverObject,
IN PUNICODE_STRING usRegistryPath
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING usDeviceName = RTL_CONSTANT_STRING(NT_DEVICE_NAME);
UNICODE_STRING usSymbolLink = RTL_CONSTANT_STRING(DOS_DEVICE_NAME);
PDEVICE_OBJECT pstDevObject = NULL;
PPROC_PROTECT_DEVICEEXTENSION pstDeviceExtension = NULL;
ULONG ulIndex = NULL;
/*
* 创建设备。。。
*/
DbgPrint("the driver is loading .....\n");
ntStatus = IoCreateDevice(
pstDriverObject,
sizeof(*pstDeviceExtension),
&usDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pstDevObject );
if ( !NT_SUCCESS( ntStatus ) )
{
DbgPrint(
"can not create the device object , error code is 0x%x .\n",
ntStatus
);
goto __error_end;
}
AddFlag(pstDevObject->Flags,DO_DEVICE_INITIALIZING);
/*
* 设备扩张信息和全局变量的初始化
*/
pstDeviceExtension = (PPROC_PROTECT_DEVICEEXTENSION)(pstDevObject->DeviceExtension);
if(!pstDeviceExtension) goto __error_end;
pstDeviceExtension->ulProcId = g_ulProcId = -1;
pstDeviceExtension->blEnableProt = g_blEnableProt = FALSE;
InterlockedExchangePointer(&g_OldZwOpenProcess,SYSTEMSERVICE(ZwOpenProcess));
//pstDeviceExtension->pZwOpenProcess = g_OldZwOpenProcess;
InterlockedExchangePointer(&pstDeviceExtension->pZwOpenProcess,g_OldZwOpenProcess);
/*
* 创建设备连接符。。。
*/
ntStatus = IoCreateSymbolicLink(&usSymbolLink,&usDeviceName);
if(!NT_SUCCESS(ntStatus))
{
DbgPrint(
"can not create the symbol link , error code is 0x%x .\n",
ntStatus
);
goto __error_end;
}
/*
* 设置分发处理例程
*/
for(ulIndex=0;ulIndex<=IRP_MJ_MAXIMUM_FUNCTION;ulIndex++)
pstDriverObject->MajorFunction[ulIndex] = OnIrpDefaultRoutine;
pstDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OnIprDeviceControlRoutine;
// 支持动态卸载
pstDriverObject->DriverUnload = DriverUnload;
// SSDT Hook,HOOK掉NtOpenProcess来实现进程保护
DisableMemProtect();
InterlockedExchangePointer(&SYSTEMSERVICE(ZwOpenProcess),NewZwOpenProcess);
RecoverMemProtect();
// 所有初始化完成
ClearFlag(pstDevObject->Flags,DO_DEVICE_INITIALIZING);
__error_end:
if(!NT_SUCCESS(ntStatus))
{
if(pstDevObject) IoDeleteDevice(pstDevObject);
IoDeleteSymbolicLink(&usSymbolLink);
}
return ntStatus;
}
------------------------------------------------------------------------------------
//头文件ProtProtect.h源代码
#include "ntddk.h"
#define NT_DEVICE_NAME L"\\Device\\ProtectProcess"
#define DOS_DEVICE_NAME L"\\DosDevices\\ProtectProcess"
//////////////////////////////////////////////////////////////////////////
#define IOCTL_ENABLE_PROTECT \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISABLE_PROTECT \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_CHANGLE_PROCESS \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x802,METHOD_BUFFERED,FILE_ANY_ACCESS)
//////////////////////////////////////////////////////////////////////////
/*
* 系统的SSDT服务例程表
*/
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function) \
KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]
//////////////////////////////////////////////////////////////////////////
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
);
typedef NTSTATUS ZW_OPEN_PROCESS(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
);
typedef ZW_OPEN_PROCESS *PZW_OPEN_PROCESS;
//////////////////////////////////////////////////////////////////////////
#define DisableMemProtect() \
{\
__asm cli\
__asm mov eax,cr0\
__asm push eax\
__asm and eax,(~0x10000)\
__asm mov cr0,eax\
}
#define RecoverMemProtect() \
{\
__asm pop eax\
__asm or eax,0x10000\
__asm mov cr0,eax\
__asm sti\
}
#ifndef AddFlag(_flag,_add)
#define AddFlag(_flag,_add) (_flag) |= (_add)
#endif
#ifndef ClearFlag(_flags,_clear)
#define ClearFlag(_flags,_clear) (_flags) &= (~(_clear))
#endif
//////////////////////////////////////////////////////////////////////////
/*
* 设备扩展信息
*/
typedef struct _PROC_PROTECT_DEVICEEXTENSION
{
PZW_OPEN_PROCESS pZwOpenProcess;
ULONG ulProcId;
ULONG blEnableProt;
}PROC_PROTECT_DEVICEEXTENSION,*PPROC_PROTECT_DEVICEEXTENSION;
编译环境 VS2008 + WDK
error PRJ0002 : 错误的结果 255 (从“C:\WINDOWS\System32\cmd.exe”返回)
附上源代码:
//头文件ProtProtect.h源代码在下面附上
#include "ProtProtect.h"
PZW_OPEN_PROCESS g_OldZwOpenProcess;
ULONG g_ulProcId = -1;
ULONG g_blEnableProt = FALSE;
NTSTATUS NewZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
// 如果打开的进程是我们要保护的进程,就返回STATUS_ACCESS_DENIED
// 进程用户打开
if((g_blEnableProt==TRUE) && (ClientId->UniqueProcess==g_ulProcId))
{
DbgPrint("保护进程 g_ulProcId:%ld\n",g_ulProcId);
return STATUS_ACCESS_DENIED;
}
// 如果不是我们要保护的进程,就交给原例程处理
return g_OldZwOpenProcess(
ProcessHandle,
DesiredAccess,
ObjectAttributes,
ClientId
);
}
NTSTATUS OnIrpDefaultRoutine(
IN PDEVICE_OBJECT pstDeviceObject,
IN PIRP pstIrp
)
{
pstIrp->IoStatus.Status = STATUS_SUCCESS;
pstIrp->IoStatus.Information = 0;
IoCompleteRequest(pstIrp,IO_NO_INCREMENT);
}
VOID DriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
UNICODE_STRING usSymbolLink = RTL_CONSTANT_STRING(DOS_DEVICE_NAME);
PDEVICE_OBJECT pstDevObj = NULL;
// 删除设备连接符
IoDeleteSymbolicLink(&usSymbolLink);
if(DriverObject)
{
// 删除驱动创建的所有设备
pstDevObj=DriverObject->DeviceObject;
while(pstDevObj)
{
IoDeleteDevice(pstDevObj);
pstDevObj = pstDevObj->NextDevice;
}
}
DbgPrint("now , unhook the NtOpenProcess routine !\n");
DisableMemProtect();
InterlockedExchangePointer(&(SYSTEMSERVICE(ZwOpenProcess)),g_OldZwOpenProcess);
RecoverMemProtect();
DbgPrint("the driver has been unloaded !\n");
}
NTSTATUS OnIprDeviceControlRoutine(
IN PDEVICE_OBJECT pstDeviceObject,
IN PIRP pstIrp
)
{
NTSTATUS ntStatus;
ULONG ulCtlCode = 0;
PIO_STACK_LOCATION pstStackLocation = NULL;
PPROC_PROTECT_DEVICEEXTENSION pstDevExtension = NULL;
pstStackLocation = IoGetCurrentIrpStackLocation(pstIrp);
pstDevExtension = \
(PPROC_PROTECT_DEVICEEXTENSION)pstDeviceObject->DeviceExtension;
pstIrp->IoStatus.Information = 0;
/*
* IRP_MJ_DEVICE_CONTROL的分发处理例程。。。
*/
if(pstStackLocation->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
switch(pstStackLocation->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_CHANGLE_PROCESS:
{
//g_ulProcId = *(ULONG *)pstIrp->AssociatedIrp.SystemBuffer;
pstDevExtension->ulProcId = *(ULONG *)pstIrp->AssociatedIrp.SystemBuffer;
InterlockedExchange(&g_ulProcId,pstDevExtension->ulProcId);
/*
DbgPrint("===========================\n");
DbgPrint("IOCTL_PROTECT_CONTROL 被调用,通讯成功!\n");
DbgPrint("输入缓冲区大小: %d\n",\
pstStackLocation->Parameters.DeviceIoControl.InputBufferLength);
DbgPrint("输出缓冲区大小: %d\n",\
pstStackLocation->Parameters.DeviceIoControl.OutputBufferLength);
DbgPrint("输入缓冲区地址: %ld\n",\
pstStackLocation->Parameters.DeviceIoControl.Type3InputBuffer);
DbgPrint("当前保护进程ID: %ld\n",pstDevExtension->ulProcId);
DbgPrint("===========================\n");
//strcpy(Irp->UserBuffer,"OK!\n");
*/
ntStatus = STATUS_SUCCESS;
break;
}
case IOCTL_ENABLE_PROTECT:
{
pstDevExtension->blEnableProt = TRUE;
pstDevExtension->ulProcId = *(ULONG *)pstIrp->AssociatedIrp.SystemBuffer;
InterlockedExchange(&g_blEnableProt,pstDevExtension->blEnableProt);
InterlockedExchange(&g_ulProcId,pstDevExtension->ulProcId);
ntStatus = STATUS_SUCCESS;
break;
}
case IOCTL_DISABLE_PROTECT:
{
pstDevExtension->blEnableProt = FALSE;
ntStatus = STATUS_SUCCESS;
break;
}
default:
{
DbgPrint("it should be run here , something must be wrong !\n");
ntStatus = STATUS_ACCESS_DENIED;
break;
}
}
}
else
{
DbgPrint("it should be run here , something must be wrong !\n");
ntStatus = STATUS_ACCESS_DENIED;
}
pstIrp->IoStatus.Status = ntStatus;
IoCompleteRequest(pstIrp,IO_NO_INCREMENT);
return ntStatus;
}
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT pstDriverObject,
IN PUNICODE_STRING usRegistryPath
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING usDeviceName = RTL_CONSTANT_STRING(NT_DEVICE_NAME);
UNICODE_STRING usSymbolLink = RTL_CONSTANT_STRING(DOS_DEVICE_NAME);
PDEVICE_OBJECT pstDevObject = NULL;
PPROC_PROTECT_DEVICEEXTENSION pstDeviceExtension = NULL;
ULONG ulIndex = NULL;
/*
* 创建设备。。。
*/
DbgPrint("the driver is loading .....\n");
ntStatus = IoCreateDevice(
pstDriverObject,
sizeof(*pstDeviceExtension),
&usDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pstDevObject );
if ( !NT_SUCCESS( ntStatus ) )
{
DbgPrint(
"can not create the device object , error code is 0x%x .\n",
ntStatus
);
goto __error_end;
}
AddFlag(pstDevObject->Flags,DO_DEVICE_INITIALIZING);
/*
* 设备扩张信息和全局变量的初始化
*/
pstDeviceExtension = (PPROC_PROTECT_DEVICEEXTENSION)(pstDevObject->DeviceExtension);
if(!pstDeviceExtension) goto __error_end;
pstDeviceExtension->ulProcId = g_ulProcId = -1;
pstDeviceExtension->blEnableProt = g_blEnableProt = FALSE;
InterlockedExchangePointer(&g_OldZwOpenProcess,SYSTEMSERVICE(ZwOpenProcess));
//pstDeviceExtension->pZwOpenProcess = g_OldZwOpenProcess;
InterlockedExchangePointer(&pstDeviceExtension->pZwOpenProcess,g_OldZwOpenProcess);
/*
* 创建设备连接符。。。
*/
ntStatus = IoCreateSymbolicLink(&usSymbolLink,&usDeviceName);
if(!NT_SUCCESS(ntStatus))
{
DbgPrint(
"can not create the symbol link , error code is 0x%x .\n",
ntStatus
);
goto __error_end;
}
/*
* 设置分发处理例程
*/
for(ulIndex=0;ulIndex<=IRP_MJ_MAXIMUM_FUNCTION;ulIndex++)
pstDriverObject->MajorFunction[ulIndex] = OnIrpDefaultRoutine;
pstDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OnIprDeviceControlRoutine;
// 支持动态卸载
pstDriverObject->DriverUnload = DriverUnload;
// SSDT Hook,HOOK掉NtOpenProcess来实现进程保护
DisableMemProtect();
InterlockedExchangePointer(&SYSTEMSERVICE(ZwOpenProcess),NewZwOpenProcess);
RecoverMemProtect();
// 所有初始化完成
ClearFlag(pstDevObject->Flags,DO_DEVICE_INITIALIZING);
__error_end:
if(!NT_SUCCESS(ntStatus))
{
if(pstDevObject) IoDeleteDevice(pstDevObject);
IoDeleteSymbolicLink(&usSymbolLink);
}
return ntStatus;
}
------------------------------------------------------------------------------------
//头文件ProtProtect.h源代码
#include "ntddk.h"
#define NT_DEVICE_NAME L"\\Device\\ProtectProcess"
#define DOS_DEVICE_NAME L"\\DosDevices\\ProtectProcess"
//////////////////////////////////////////////////////////////////////////
#define IOCTL_ENABLE_PROTECT \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_DISABLE_PROTECT \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_CHANGLE_PROCESS \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x802,METHOD_BUFFERED,FILE_ANY_ACCESS)
//////////////////////////////////////////////////////////////////////////
/*
* 系统的SSDT服务例程表
*/
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function) \
KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]
//////////////////////////////////////////////////////////////////////////
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
);
typedef NTSTATUS ZW_OPEN_PROCESS(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
);
typedef ZW_OPEN_PROCESS *PZW_OPEN_PROCESS;
//////////////////////////////////////////////////////////////////////////
#define DisableMemProtect() \
{\
__asm cli\
__asm mov eax,cr0\
__asm push eax\
__asm and eax,(~0x10000)\
__asm mov cr0,eax\
}
#define RecoverMemProtect() \
{\
__asm pop eax\
__asm or eax,0x10000\
__asm mov cr0,eax\
__asm sti\
}
#ifndef AddFlag(_flag,_add)
#define AddFlag(_flag,_add) (_flag) |= (_add)
#endif
#ifndef ClearFlag(_flags,_clear)
#define ClearFlag(_flags,_clear) (_flags) &= (~(_clear))
#endif
//////////////////////////////////////////////////////////////////////////
/*
* 设备扩展信息
*/
typedef struct _PROC_PROTECT_DEVICEEXTENSION
{
PZW_OPEN_PROCESS pZwOpenProcess;
ULONG ulProcId;
ULONG blEnableProt;
}PROC_PROTECT_DEVICEEXTENSION,*PPROC_PROTECT_DEVICEEXTENSION;
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
- [原创]一个菜鸟的内核学习——注册表恶意驱动 17124
- 一个菜鸟的内核学习——Win7内核隐藏进程 19012
- 一个菜鸟的内核学习 4181
- [求助]编译驱动提示这样的错误怎么办? 1191
- [求助]初学驱动编程,求指示 1454
看原图
赞赏
雪币:
留言: