再谈进程与端口的映射

端口检测工具fport实战解析 fport是一个专为网络诊断和系统安全设计的实用工具,它能够将端口与运行在系统上的进程进行关联,帮助用户快速定位哪些程序正在使用网络资源。与传统的网络命令(如netstat)相比,fport提供了更直观、更高效的端口与进程映射视图,是系统管理员和网络安全工程师不可或缺的工具之一。本章将从fport的起源与发展入手,逐步深入其核心功能,最后探讨其在系统管理和网络安全中的典型应用场景,帮助读者全面了解该工具的使用价值。fport。 阅读详情
关于进程与端口映射的文章已经有很多了,我把我对fport的分析也写出来,让大家知道fport是如何工作的.
fport.exe是由foundstone team出品的免费软件,可以列出系统中所有开放的端口都是由那些进程打开的.而下
面所描述的方法是基于fport v1.33的,如果和你机器上的fport有出入,请检查fport版本.

    首先,它检测当前用户是否拥有管理员权限(通过读取当前进程的令牌可知当前用户是否具有管理权限,请参考
相关历程),如果没有,打印一句提示后退出,然后设置当前进程的令牌,接着,用ZwOpenSection函数打开内核对象
/Device/PhysicalMemory,这个对象用于对系统物理内存的访问.ZwOpenSection函数的原型如下:

NTSYSAPI
NTSTSTUS
NTAPI
ZwOpenSection(
    Out PHANDLE sectionHandle;
    IN ACCESS_MASK DesiredAccess;
    IN POBJECT_ATTRIBUTES ObjectAttributes
    };
(见ntddk.h)

第一个参数得到函数执行成功后的句柄
第二个参数DesiredAccess为一个常数,可以是下列值:
    #define SECTION_QUERY 0x0001
    #define SECTION_MAP_WRITE 0x0002
    #define SECTION_MAP_READ 0x0004
    #define SECTION_MAP_EXECUTE 0x0008
    #define SECTION_EXTEND_SIZE 0x0010

    #define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY|/
                            SECTION_MAP_WRITE | /
                            SECTION_MAP_READ | /
                            SECTION_MAP_EXECUTE | /
                            SECTION_EXTEND_SIZE)
    (见ntddk.h)
第三个参数是一个结构,包含要打开的对象类型等信息,结构定义如下:
    typedef struct _OBJECT_ATTRIBUTES {
        ULONG Length;
        HANDLE RootDirectory;
        PUNICODE_STRING ObjectName;
        ULONG Attributes;
        PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
        PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
    } OBJECT_ATTRIBUTES;
    typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
    (见ntdef.h)
对于这个结构的初始化用一个宏完成:
    #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; /
        }
    (见ntdef.h)
那么,打开内核对象/Device/PhysicalMemory的语句如下:
WCHAR PhysmemName[] = L"//Device//PhysicalMemory";
void * pMapPhysicalMemory;
HANDLE pHandle;

bool OpenPhysicalMemory()
{
    NTSTATUS status;
    UNICODE_STRING physmemString;
    OBJECT_ATTRIBUTES attributes;
    RtlInitUnicodeString( =physmemString, PhysmemName ); //初始化Unicode字符串,函数原型见ntddk.h
    InitializeObjectAttributes( =attributes, =physmemString,
                     OBJ_CASE_INSENSITIVE, NULL, NULL ); //初始化OBJECT_ATTRIBUTES结构
    status = ZwOpenSection(pHandle, SECTION_MAP_READ, =attributes ); //打开内核对象/Device/PhysicalMemory,获得句柄
    if( !NT_SUCCESS( status ))
        return false;
    pMapPhysicalMemory=MapViewOfFile(pHandle,FILE_MAP_READ,
                           0,0x30000,0x1000);
    //从内存地址0x30000开始映射0x1000个字节
    if( GetLastError()!=0)
        return false;
    return true;
}

    为什么要从0x30000开始映射呢,是这样,我们知道,在Windows NT/2000下,系统分为内核模式和用户模式,也就是我们
所说的Ring0和Ring3,在Windows NT/2000下,我们所能够看到的进程都运行在Ring3下,一般情况下,系统进程(也就是System
进程)的页目录(PDE)所在物理地址地址为0x30000,或者说,系统中最小的页目录所在的物理地址为0x30000.而页目录(PDE)由
1024项组成,每项均指向一页表(PTE),每一页表也由1024个页组成,而每页的大小为4K,1024*4=4096(0x1000),所以,上面从物
理地址0x30000开始映射了0x1000个字节.(具体描述见WebCrazy的文章<<小议Windows NT/2000的分页机制>>)

    程序打开打开内核对象/Device/PhysicalMemory后,继续用函数ZwOpenFile打开内核对象/Device/Tcp和Device/Udp,ZwOpenFile
函数的原型如下:
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenFile(
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG ShareAccess,
    IN ULONG OpenOptions
    );
(见ntddk.h)

第一个参数返回打开对象的句柄
第二个参数DesiredAccess为一个常数,可以是下列值:
    #define FILE_READ_DATA ( 0x0001 ) // file = pipe
    #define FILE_LIST_DIRECTORY ( 0x0001 ) // directory
    #define FILE_WRITE_DATA ( 0x0002 ) // file = pipe
    #define FILE_ADD_FILE ( 0x0002 ) // directory
    #define FILE_APPEND_DATA ( 0x0004 ) // file
    #define FILE_ADD_SUBDIRECTORY ( 0x0004 ) // directory
    #define FILE_CREATE_PIPE_INSTANCE ( 0x0004 ) // named pipe
    #define FILE_READ_EA ( 0x0008 ) // file = directory
    #define FILE_WRITE_EA ( 0x0010 ) // file = directory
    #define FILE_EXECUTE ( 0x0020 ) // file
    #define FILE_TRAVERSE ( 0x0020 ) // directory
    #define FILE_DELETE_CHILD ( 0x0040 ) // directory
    #define FILE_READ_ATTRIBUTES ( 0x0080 ) // all
    #define FILE_WRITE_ATTRIBUTES ( 0x0100 ) // all
    #define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
    #define FILE_GENERIC_READ (STANDARD_RIGHTS_READ |/
                                       FILE_READ_DATA |/
                                       FILE_READ_ATTRIBUTES |/
                                       FILE_READ_EA |/
                                       SYNCHRONIZE)
    #define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |/
                                       FILE_WRITE_DATA |/
                                       FILE_WRITE_ATTRIBUTES |/
                                       FILE_WRITE_EA |/
                                       FILE_APPEND_DATA |/
                                       SYNCHRONIZE)
    #define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE |/
                                       FILE_READ_ATTRIBUTES |/
                                       FILE_EXECUTE |/
                                       SYNCHRONIZE)
        (见ntdef.h)
第三个参数是一个结构,包含要打开的对象类型等信息,结构定义见上面所述
第四个参数返回打开对象的属性,是一个结构,定义如下:
    typedef struct _IO_STATUS_BLOCK {
        union {
            NTSTATUS Status;
            PVOID Pointer;
        };

        ULONG_PTR Information;
    } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

    #if defined(_WIN64)
    typedef struct _IO_STATUS_BLOCK32 {
        NTSTATUS Status;
        ULONG Information;
    } IO_STATUS_BLOCK32, *PIO_STATUS_BLOCK32;
    #endif
    (见ntddk.h)
第五个参数ShareAccess是一个常数,可以是下列值:
    #define FILE_SHARE_READ 0x00000001 // winnt
    #define FILE_SHARE_WRITE 0x00000002 // winnt
    #define FILE_SHARE_DELETE 0x00000004 // winnt
    (见ntddk.h)
第六个参数OpenOptions也是一个常数,可以是下列的值:
    #define FILE_DIRECTORY_FILE 0x00000001
    #define FILE_WRITE_THROUGH 0x00000002
    #define FILE_SEQUENTIAL_ONLY 0x00000004
    #define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
    #define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
    #define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
    #define FILE_NON_DIRECTORY_FILE 0x00000040
    #define FILE_CREATE_TREE_CONNECTION 0x00000080
    #define FILE_COMPLETE_IF_OPLOCKED 0x00000100
    #define FILE_NO_EA_KNOWLEDGE 0x00000200
    #define FILE_OPEN_FOR_RECOVERY 0x00000400
    #define FILE_RANDOM_ACCESS 0x00000800
    #define FILE_DELETE_ON_CLOSE 0x00001000
    #define FILE_OPEN_BY_FILE_ID 0x00002000
    #define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
    #define FILE_NO_COMPRESSION 0x00008000
    #define FILE_RESERVE_OPFILTER 0x00100000
    #define FILE_OPEN_REPARSE_POINT 0x00200000
    #define FILE_OPEN_NO_RECALL 0x00400000
    #define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
    #define FILE_COPY_STRUCTURED_STORAGE 0x00000041
    #define FILE_STRUCTURED_STORAGE 0x00000441
    #define FILE_VALID_OPTION_FLAGS 0x00ffffff
    #define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032
    #define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
    #define FILE_VALID_SET_FLAGS 0x00000036
    (见ntddk.h)
        
那么,打开内核对象/Device/Tcp和/Device/Udp的语句如下:
WCHAR physmemNameTcp[]=L"//Device//TCP";
WCHAR physmemNameUdp[]=L"//Device//UDP";
HANDLE pTcpHandle;
HANDLE pUdpHandle;

HANDLE OpenDeviceTcpUdp(WCHAR * deviceName)
{
    NTSTATUS status;
    UNICODE_STRING physmemString;
    OBJECT_ATTRIBUTES attributes;
    IO_STATUS_BLOCK iosb;
    HANDLE pDeviceHandle;

    RtlInitUnicodeString(=physmemString, deviceName);
    if(GetLastError()!=0)
        return NULL;
    InitializeObjectAttributes( =attributes,=physmemString,
                            OBJ_CASE_INSENSITIVE,0, NULL );
    status = ZwOpenFile ( =pDeviceHandle,0x100000, =attributes, =iosb, 3,0);
    if( !NT_SUCCESS( status ))
        return NULL;
}

    接着,程序用ZwQuerySystemInformation函数获得系统当前所以进程的所建立的句柄及其相关信息,函数的原型如下:
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
    IN OUT PVOID SystemInformation,
    IN ULONG SystemInformatio浔?这样,我们可以在上面获得的句柄列表中的当前进程中查找对象句柄的
数值和我们保存的两个打开的内核对象的句柄数值相同的句柄,并得到其句柄所指向的内核对象的地址.代码如下:
DWORD TcpHandle;
DWORD UdpHandle;
DWORD GetTcpUdpObject(PULONG pBuffer,HANDLE pHandle,DWORD ProcessId)
{
    DWORD objTYPE1,objTYPE2,HandleObject;

    PSYSTEM_HANDLE_INFORMATION pProcesses = (PSYSTEM_HANDLE_INFORMATION)(pBuffer+1);
  
    for (i=0;i< * pBuffer;i++)
    {
        if ((pProcesses.ProcessID) == ProcessId)
        {
            objTYPE1 = (DWORD)hDeviceTcpUdp;
            objTYPE2 = (DWORD)pProcesses.Handle;
            if(objTYPE1==objTYPE2)
            {
                HandleObject = (DWORD)pProcesses.Object;
                return HandleObject;
        }
    }
    return 0;
}

这个内核对象地址是一个线性地址,我们需要把这个地址转换为物理地址,并得到一些相关的数据.在fport中,换算是这样进行的:
(具体描述见WebCrazy的文章<<小议Windows NT/2000的分页机制>>)
void * NewmapPhy;

void GetPTE(DWORD objAddress)
{
    DWORD physmemBuff;
    DWORD newAddress1,newAddress2,newAddress3,newAddress4;
    DWORD * newAddress;

    physmemBuff = (DWORD)pMapPhysicalMemory;
    newAddress1 = physmemBuff+(objAddress>>0x16)*4;
    newAddress = (DWORD *)newAddress1;
    newAddress1 = * newAddress;
    newAddress2 = objAddress = 0x3FF000;
    newAddress3 = newAddress1 = 0x0FFFFF000;
    newAddress4 = newAddress2 + newAddress3;
    NewmapPhy = MapViewOfFile(ghPhysicalMemory,FILE_MAP_READ,0,newAddress4,0x1000);
    //重新映射物理内存,得到当前线性地址所指向的PTE的物理地址内容
}

然后在根据内核对象的线性地址得到这个地址所指向的物理页,得到体现当前内核对象内容的页,其结构如下:
typedef struct {
    ULONG Present;
    ULONG WriteTable;
    ULONG User;
    ULONG WriteThru;
    ULONG NoCache;
    ULONG Accessed;
    ULONG Dirty;
    ULONG PageSize;
    ULONG Global;
    ULONG Available;
    ULONG Pfn;
} PTE, *PPTE;
(注:我不能保证这个结构的正确性,但我们只会用到其中的两个值,对程序来说,这个结构是可以工作的,^_^)
代码如下:
ULONG CurrWriteTable;
ULONG NoCache;

void GetMustPar(DWORD objAddress)
{
    DWORD CurrAddress;
    CurrAddress = objAddress = 0xFFF;
    PPTE pte = (PPTE)(VOID *)((DWORD)NewmapPhy+CurrAddress);
    CurrWriteTable = pte->WriteTable;
    CurrNoCache = Pte->NoCache;
}

好了,我们现在想要得到的都已经得到了,下面需要做的是遍历进程,用每一个进程中的每一个句柄(呵呵,不是每一个句柄,
在Windows NT下,/Device/Tcp和/Device/Udp的句柄类型值为0x16,在Windows 2000下这个值为0x1A)的核心地址用上面所描
述的办法得到其PTE内容,得到其WriteTable值,如果与内核对象/Device/Tcp和/Device/Udp相等,那么这个句柄就有可能打开
了一个端口,再对这个句柄进行确认,就可以了.确认的代码如下:
typedef struct _TDI_CONNECTION_INFO {
    ULONG State;
    ULONG Event;
    ULONG TransmittedTsdus;
    ULONG ReceivedTsdus;
    ULONG TransmissionErrors;
    ULONG ReceiveErrors;
    LARGE_INTEGER Throughput;
    LARGE_INTEGER Delay;
    ULONG SendBufferSize;
    ULONG ReceiveBufferSize;
    BOOLEAN Unreliable;
} TDI_CONNECTION_INFO, *PTDI_CONNECTION_INFO;

typedef struct _TDI_CONNECTION_INFORMATION {
    LONG UserDataLength;
    PVOID UserData;
    LONG OptionsLength;
    PVOID Options;
    LONG RemoteAddressLength;
    PVOID RemoteAddress;
} TDI_CONNECTION_INFORMATION, *PTDI_CONNECTION_INFORMATION;
(以上结构见tdi.h)

void GetOpenPort(DWORD dwProcessesID,USHORT Handle,int NoCache)
//dwProcessesID为进程标识ID
//Handle为进程打开的句柄,并且经过比较为/Device/Tcp或/Device/Udp类型
//NoCache为PTE结构中的一个值
{
    HANDLE hProc,DupHandle=NULL;
    HANDLE hEven=NULL;
        OVERLAPPED overlap;
    u_short openport;
    int i=0;
    char procName[256]={0};
    int portflag=0;

    overlap.Internal = 0;
    overlap.InternalHigh = 0;
    overlap.Offset = 0;
    overlap.OffsetHigh = 0;
    hEven=CreateEvent(0,1,0,0);
    overlap.hEvent = hEven;

    hProc = OpenProcess(PROCESS_DUP_HANDLE,
                        0,
                        dwProcessesID);
    if(hProc)
    {
        DuplicateHandle(hProc,
                        (HANDLE)Handle,
                        GetCurrentProcess(),
                        =DupHandle,
                        0,
                        FALSE,
                        2);
        CloseHandle( hProc );
        if(DupHandle)
        {
            TDI_CONNECTION_INFO TdiConnInfo={0};
            TDI_CONNECTION_INFORMATION TdiConnInformation={0};
            DWORD dwRetu=0;

            if(NoCache==0x2)
            {
                TdiConnInformation.RemoteAddressLength= 4;
                if(DeviceIoControl(DupHandle,0x210012,
                            =TdiConnInformation,sizeof(TdiConnInformation),
                            =TdiConnInfo,sizeof(TdiConnInfo),
                            0,=overlap))
                //进行TDI查询,得到连接的相关信息
                {
                    openport = ntohs((u_short)TdiConnInfo.ReceivedTsdus);
                    procname = GetProcName(dwProcessesID); //得到进程标识ID的进程名称
                    printf("PID = %4d ProcessName = %15s PORT = %4d/n",dwProcessesID,procName,openport);
                }
            }
            if(NoCache==0x1)
            {
                TdiConnInformation.RemoteAddressLength= 3;
                if(DeviceIoControl(DupHandle,0x210012,
                            =TdiConnInformation,sizeof(TdiConnInformation),
                            =TdiConnInfo,sizeof(TdiConnInfo),
                            0,=overlap))
                //进行TDI查询,得到连接的相关信息
                {
                    openport = ntohs((u_short)TdiConnInfo.ReceivedTsdus);
                    procname = GetProcName(dwProcessesID); //得到进程标识ID的进程名称
                    printf("PID = %4d ProcessName = %15s PORT = %4d/n",dwProcessesID,procName,openport);
                }
            }
        }
    }
    CloseHandle(hEven);
    CloseHandle(DupHandle);
}

以上是我对fport.exe的分析及其实现代码,演示程序可以从whitecell.org下载,如果你发现有问题,请通知我,^_^

参考:

fport.exe
Gary Nebbett<<Windows NT/2000 Native API Reference>>
WebCrazy<<小议Windows NT/2000分页机制>>
NTDDK
深入掌握端口查看工具:Fport.exe的使用与原理 本文还有配套的精品资源,点击获取 简介:端口是TCP/IP协议栈中用于应用程序通信的关键部分,范围从0到65535。理解端口查看工具的原理和使用方法对于网络诊断和应用调试至关重要。本文将介绍端口查看工具的原理,并详细说明如何使用 Fport.exe 这一特定工具。通过命令行查看端口占用情况, Fport.exe 能显示端口号、协议、本地地址、进程... 阅读详情

相关推荐

Fport

Fport是FoundStone出品的一个用来列出系统中所有打开的TCP/IP和UDP端口,以及它们对应应用程序的完整路径、PID标识、进程名称等信息的软件。在命令行下使用,请看例子: <br><br>C:\>fport<br>FPort v2.0 - TCP/IP Process to Port Mapper<br>Copyright 2000 by Foundstone, Inc.<br>http://www.foundstone.com<br><br>Pid Process Port Proto Path<br>1296 inetinfo -> 21 TCP C:\WINNT\System32\inetsrv\inetinfo.exe<br>1296 inetinfo -> 25 TCP C:\WINNT\System32\inetsrv\inetinfo.exe<br>1296 inetinfo -> 80 TCP C:\WINNT\System32\inetsrv\inetinfo.exe<br>

端口检测工具Fport的使用

一、背景开发中经常要进行冲突端口的检查,可通过命令行操作,请参看我曾经发表过一篇文章:《windows和linux中检查端口是否被占用》http://blog.youkuaiyun.com/woshixuye/article/details/12706143二、fport工具这个工具使用起来非常方便,是一个.exe的小工具。1、通过命令行找到该工具所在文件夹如:E:>cd E:/t...

weixin_34357928的博客 837

Fport(端口扫描软件)

Fort是一款TCP/IP端口扫描软件它可以扫描出所运行计算机上与外界所开放的TCP/IP端口 将文件解压下来运行Port.bat 然后查看Port.txt Port.txt即为本机所看房TCP/IP端口

端口映射查看工具Fport的使用方法

今天在《深入体验Java Web开发内幕--核心基础》上看到作者推荐使用Fport工具,它与netstat -na的结果不同的是:Fport可以更好的显示结果,显示出哪个应用程序占用了哪个端口,并且可以对结果排序显示。很方便。 但是初次使用,会出现问题:运行Fport.exe时,跳出一个运行窗口,很快就消失,来不及查看就没有了。 原因是因为Fport是一个DOS工具,在WINDOWS环境下打开就自...

珍惜生命,过好每一天 2761

Fport-2.0(端口查看工具)

Readme for fport v2.0 fport supports Windows NT4, Windows 2000 and Windows XP fport reports all open TCP/IP and UDP ports and maps them to the owning application. This is the same information you would see using the 'netstat -an' command, but it also maps those ports to running processes with the PID, process name and path. Fport can be used to quickly identify unknown open ports and their associated applications. Usage: C:\>fport FPort v2.0 - TCP/IP Process to Port Mapper Copyright 2000 by Foundstone, Inc. http://www.foundstone.com Pid Process Port Proto Path 392 svchost -> 135 TCP C:\WINNT\system32\svchost.exe 8 System -> 139 TCP 8 System -> 445 TCP 508 MSTask -> 1025 TCP C:\WINNT\system32\MSTask.exe 392 svchost -> 135 UDP C:\WINNT\system32\svchost.exe 8 System -> 137 UDP 8 System -> 138 UDP 8 System -> 445 UDP 224 lsass -> 500 UDP C:\WINNT\system32\lsass.exe 212 services -> 1026 UDP C:\WINNT\system32\services.exe The program contains five (5) switches. The switches may be utilized using either a '/' or a '-' preceding the switch. The switches are; Usage: /? usage help /p sort by port /a sort by application /i sort by pid /ap sort by application path

fport和fport说明

fport Readme for fport v2.0 fport supports Windows NT4, Windows 2000 and Windows XP fport reports all open TCP/IP and UDP ports and maps them to the owning application. This is the same information you would see using the 'netstat -an' command, but it also maps those ports to running processes with the PID, process name and path. Fport can be used to quickly identify unknown open ports and their associated applications. Usage: C:\>fport FPort v2.0 - TCP/IP Process to Port Mapper Copyright 2000 by Foundstone, Inc. http://www.foundstone.com Pid Process Port Proto Path 392 svchost -> 135 TCP C:\WINNT\system32\svchost.exe 8 System -> 139 TCP 8 System -> 445 TCP 508 MSTask -> 1025 TCP C:\WINNT\system32\MSTask.exe 392 svchost -> 135 UDP C:\WINNT\system32\svchost.exe 8 System -> 137 UDP 8 System -> 138 UDP 8 System -> 445 UDP 224 lsass -> 500 UDP C:\WINNT\system32\lsass.exe 212 services -> 1026 UDP C:\WINNT\system32\services.exe The program contains five (5) switches. The switches may be utilized using either a '/' or a '-' preceding the switch. The switches are; Usage: /? usage help /p sort by port /a sort by application /i sort by pid /ap sort by application path For updates visit: www.foundstone.com

fport mport pskill

fport fport 为一款第三方插件. 安装到本机后, 直接将其同名.exe(fport.exe) 复制到C盘根目录. 再进入cmd模式下, 切换到C: ; 输入 fport命令, ...

945

PyQtWebEngine安装避坑指南:快速解决ModuleNotFoundError

本文详细解析了PyQt5开发中常见的ModuleNotFoundError: No module named 'PyQt5.QtWebEngineWidgets'错误。核心原因是PyQt5 5.11版本后,网页引擎组件被独立为PyQtWebEngine包。文章对比了退回旧版本、独立安装及使用Conda等多种解决方案,并提供了针对Windows、macOS和Linux不同平台的实战安装指南与验证方法,帮助开发者快速解决依赖问题。

weixin_29056101的博客 427

再谈进程与端口的映射》之狗尾续貂篇

作 者:hhhkkk [hhkkk@126.com]拜读了ILSY 的大作《再谈进程与端口的映射》后,觉得很不错,用vc在电脑上调试,发现有些地方能取得信息 有些地方不能更加怪的是,我的win2k上本来可以取得的,后来居然不行了。而active ports却是那样稳定,有鬼不成 靠 ,偶不信搬出OllyDdg经过调试对照发现,程序不能正常显示就是函数的OpenPhysicalMemory导致不能取

执着我一生[F.S.T] 1670

手把手教你用DLP4500投影仪玩转结构光3D扫描(附固件烧录与序列设置避坑指南)

本文详细解析了如何使用DLP4500投影仪搭建结构光3D扫描系统,涵盖硬件组装、固件烧录、图案生成与优化等全流程。重点解决了固件烧录失败、图像格式错误等常见问题,并提供了实用的避坑指南和进阶技巧,帮助读者快速掌握DLP4500在3D扫描中的应用。

weixin_42662293的博客 301

blender中合并的模型,在threejs中显示多个mesh;blender多材质烘培成一个材质

5、优化项(省略此步骤,直接进行步骤6),进入到视图着色方式(此时没有灯光,整体偏暗,如果不调整灯光,烘培出来的材质也偏暗,因此此步骤为优化项,通畅建议调整)。在右边栏进入世界环境,调整颜色。7、烘焙成功之后,新建一个材质,将第三步创建的纹理图像作为材质的纹理,连接到基础色,并把模型的材质改为此材质,其他的材质全部删除。2、处理uv,在侧边栏选择数据-uv贴图,选中使用的uv,进入编辑模式,全选,键盘u,选择智能uv投射。3、处理材质,在侧边栏选择材质,进入着色,在着色器编辑器新建一个图像纹理,新建图像。

AllBluefm的专栏 2529

(转载)《再谈进程与端口的映射》之狗尾续貂篇

《再谈进程与端口的映射》之狗尾续貂篇发布日期:2004-05-08文摘内容: 文摘出处:http://www.xfocus.net/articles/200405/695.html创建时间:2004-05-01文章属性:原创文章提交:hhhkkk (hac01_at_163.com)《再谈进程与端口的映射》之狗尾续貂篇日  期:2004-5-1作  者:hhhkkk  [hhkkk@126

Kendiv's Box 2258

Proteus 8.15仿真STM32F103C8,ADC采样总为0?别急着换芯片,先检查这3个配置

本文详细解析了在Proteus 8.15中仿真STM32F103C8时ADC采样值为0的常见原因及解决方法。从供电网络配置、时钟设置到ADC参数调整,提供了系统性的排查指南,帮助开发者快速定位问题,避免不必要的硬件更换。重点关注供电网络、时钟分频和ADC配置等关键环节。

weixin_30425949的博客 366

(转载)再谈进程与端口的映射

再谈进程与端口的映射创建时间:2002-02-05文章属性:原创文章来源:www.whitecell.org文章提交:ILSY (masteruser_at_263.net)Author  : ilsy Email   : ilsy@whitecell.org HomePage: http://www.whitecell.org 日  期:2002-02-06类  别:安全 关键字:进程 PDE

Kendiv's Box 2752

AUTOSAR 3万字面试题全面解析(持续更新)

ECU抽象层(EAL)是AUTOSAR架构中的一部分,它位于微控制器抽象层(MCAL)之下,但通常与MCAL一起被提及。EAL的目标是提供一个统一的接口来访问和管理ECU(Electronic Control Unit,电子控制单元)的硬件资源,包括处理器、存储器和外围设备。通过这种抽象,EAL使得上层软件能够以一种标准化的方式与ECU硬件交互,而不需要关心具体的硬件实现细节。EAL解决了硬件异构性带来的问题,即不同ECU可能采用不同类型的处理器和硬件配置。

大模型大数据攻城狮的专栏 5607

OPTEE常见13类问题与解答

OPTEE常见13类问题并解答

AI-安全-功耗 1203

《再谈进程与端口的映射》之狗尾续貂篇

《再谈进程与端口的映射》之狗尾续貂篇创建时间:2004-05-01文章属性:原创文章提交:hhhkkk (hac01_at_163.com)《再谈进程与端口的映射》之狗尾续貂篇日  期:2004-5-1作  者:hhhkkk  [hhkkk@126.com]拜读了ILSY 的大作《再谈进程与端口的映射》后,觉得很不错,用vc在电脑上调试,发现有些地方能取得信息 有些地方不能更加怪的是,我的wi

606

华为OD机试双机位C卷-恢复数字序列 (Py/Java/C/C++/Js/Go)

华为OD机试双机位C卷 恢复数字序列,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。华为OD机试 - 恢复数字序列。

qq_45776114的博客 1203
上一篇: 数据恢复(2)
下一篇: 小议Windows NT/2000分页机制
Matrix_Designer
博客等级 码龄16年 58粉丝 296原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值