首页
社区
课程
招聘
[求助]win7下端口进程对应关系
2009-12-17 18:03 12931

[求助]win7下端口进程对应关系

2009-12-17 18:03
12931
最近碰到一个应用程序兼容问题,winxp下面的应用程序,移植到win7下面产生了一个功能的缺失,这个功能就是进程端口对应关系列表失去。以前是使用xp下的隐藏函数AllocateAndGetUdpExTableFromStack,AllocateAndGetTcpExTableFromStack来得到这样的功能的。但是现在这个函数在win7下不能正常使用。所以就想到了先用
ZwQuerySystemInformation获取一个进程下所有的句柄,之后把所有file类型的handle都转换到自己的进程,然后强制转化成socket类型,在使用getsockname等一系列函数来获取地址。但是似乎这个方法不成立,不知道是不是自己的写法有问题,提上来求助一下,希望大家能给个建议。
1.全局变量以及函数定义
#define NT_SUCCESS(status)    ((NTSTATUS)(status)>=0)
typedef LONG NTSTATUS;
typedef enum _SYSTEM_INFORMATION_CLASS    //   Q S
{
        SystemBasicInformation,           // 00 Y N
                SystemProcessorInformation,        // 01 Y N
                SystemPerformanceInformation,       // 02 Y N
                SystemTimeOfDayInformation,        // 03 Y N
                SystemNotImplemented1,            // 04 Y N
                SystemProcessesAndThreadsInformation,  // 05 Y N
                SystemCallCounts,               // 06 Y N
                SystemConfigurationInformation,      // 07 Y N
                SystemProcessorTimes,            // 08 Y N
                SystemGlobalFlag,               // 09 Y Y
                SystemNotImplemented2,            // 10 Y N
                SystemModuleInformation,          // 11 Y N
                SystemLockInformation,            // 12 Y N
                SystemNotImplemented3,            // 13 Y N
                SystemNotImplemented4,            // 14 Y N
                SystemNotImplemented5,            // 15 Y N
                SystemHandleInformation,          // 16 Y N
                SystemObjectInformation,          // 17 Y N
                SystemPagefileInformation,         // 18 Y N
                SystemInstructionEmulationCounts,    // 19 Y N
                SystemInvalidInfoClass1,          // 20
                SystemCacheInformation,           // 21 Y Y
                SystemPoolTagInformation,          // 22 Y N
                SystemProcessorStatistics,         // 23 Y N
                SystemDpcInformation,            // 24 Y Y
                SystemNotImplemented6,            // 25 Y N
                SystemLoadImage,                // 26 N Y
                SystemUnloadImage,              // 27 N Y
                SystemTimeAdjustment,            // 28 Y Y
                SystemNotImplemented7,            // 29 Y N
                SystemNotImplemented8,            // 30 Y N
                SystemNotImplemented9,            // 31 Y N
                SystemCrashDumpInformation,        // 32 Y N
                SystemExceptionInformation,        // 33 Y N
                SystemCrashDumpStateInformation,     // 34 Y Y/N
                SystemKernelDebuggerInformation,     // 35 Y N
                SystemContextSwitchInformation,      // 36 Y N
                SystemRegistryQuotaInformation,      // 37 Y Y
                SystemLoadAndCallImage,           // 38 N Y
                SystemPrioritySeparation,          // 39 N Y
                SystemNotImplemented10,           // 40 Y N
                SystemNotImplemented11,           // 41 Y N
                SystemInvalidInfoClass2,          // 42
                SystemInvalidInfoClass3,          // 43
                SystemTimeZoneInformation,         // 44 Y N
                SystemLookasideInformation,        // 45 Y N
                SystemSetTimeSlipEvent,           // 46 N Y
                SystemCreateSession,             // 47 N Y
                SystemDeleteSession,             // 48 N Y
                SystemInvalidInfoClass4,          // 49
                SystemRangeStartInformation,        // 50 Y N
                SystemVerifierInformation,         // 51 Y Y
                SystemAddVerifier,              // 52 N Y
                SystemSessionProcessesInformation    // 53 Y N
} SYSTEM_INFORMATION_CLASS;
typedef NTSTATUS ( __stdcall *ZWQUERYSYSTEMINFORMATION)(
        IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
        IN OUT PVOID SystemInformation,
        IN ULONG SystemInformationLength,
        OUT PULONG ReturnLength OPTIONAL);

typedef ULONG(__stdcall *RTLNTSTATUSTODOSERROR)(IN NTSTATUS Status);
RTLNTSTATUSTODOSERROR fn_RtlNtStatusToDosError;
ZWQUERYSYSTEMINFORMATION fn_ZwQuerySystemInformation;
typedef struct _SYSTEM_MODULE_INFORMATION  // Information Class 11
{
        ULONG  Reserved[2];
        PVOID  Base;
        ULONG  Size;
        ULONG  Flags;
        USHORT Index;
        USHORT Unknown;
        USHORT LoadCount;
        USHORT ModuleNameOffset;
        CHAR  ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
//   ULONG ProcessId;//进程标识符
//   UCHAR ObjectTypeNumber;//打开的对象的类型
//   UCHAR Flags;//句柄属性标志
//   USHORT Handle;//句柄数值,在进程打开的句柄中唯一标识某个句柄         
//   PVOID Object;//句柄对应的EPROCESS的地址
//   ACCESS_MASK GrantedAccess;//句柄对象的访问权限
        USHORT dwPid;
        USHORT CreatorBackTraceIndex;
        BYTE   ObjType;
        BYTE   HandleAttributes;
        USHORT HndlOffset;
        DWORD  dwKeObject;
        ULONG  GrantedAccess;

} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
  ULONG NumberOfHandles;            //句柄数目
  SYSTEM_HANDLE_INFORMATION Information[1];
} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;

2.OnInitDialog()初始化函数变量的地址

        HMODULE ntdll_dll=NULL;

        if((ntdll_dll=GetModuleHandle("ntdll.dll"))==NULL)
        {
                MessageBox("GetModuleHandle() failed");
                return( FALSE );
        }

        if(!(fn_ZwQuerySystemInformation=(ZWQUERYSYSTEMINFORMATION)GetProcAddress(ntdll_dll,
                "ZwQuerySystemInformation")))
                {
                MessageBox("GetProcAddress() failed");
                return( FALSE );
        }
        if(!(fn_RtlNtStatusToDosError=(RTLNTSTATUSTODOSERROR)GetProcAddress( ntdll_dll,
                "RtlNtStatusToDosError")))
                {
                MessageBox("GetProcAddress() failed");
                return( FALSE );
        }
        WSADATA wsaData;
  int iResult = WSAStartup(MAKEWORD(1,1), &wsaData);
  if (iResult != NO_ERROR)
    MessageBox("Error at WSAStartup()\n");

3.在OnButton1() 里面做句柄的获取转换等等工作
        NTSTATUS              status;
        PSYSTEM_MODULE_INFORMATION  module=NULL;
        PSYSTEM_HANDLE_INFORMATION_EX pHandle=NULL;
        ULONG                n=0;
        ULONG                i=0;
        void                *buf=NULL;
        EnablePrivilege(SE_DEBUG_NAME);

        fn_ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&n);
        ULONG dwSize=n;
        if(NULL==(buf=malloc(dwSize)))
        {
                MessageBox("malloc() failed");
                return;
        }
        memset(buf,0,dwSize);
        status=fn_ZwQuerySystemInformation(SystemHandleInformation,buf,dwSize,&n);
        while(!NT_SUCCESS( status ))
        {
                char *errMsg;
                FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
                        fn_RtlNtStatusToDosError(status),
                        MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
                        (LPTSTR)&errMsg,0,NULL);
                if(buf!=NULL)
                        free(buf);

                dwSize+=n;
                if(dwSize>524288)
                        return;
                if(NULL==(buf=malloc(dwSize)))
                {
                        MessageBox("malloc() failed");
                        return;
                }
                memset(buf,0,dwSize);
                status=fn_ZwQuerySystemInformation(SystemHandleInformation,buf,dwSize,&n);
//                MessageBox(errMsg);
        }
        pHandle=(PSYSTEM_HANDLE_INFORMATION_EX)buf;
        for(i =0;i<pHandle->NumberOfHandles;i++)
        {
                CString strTmp,strTmp1;
                if(pHandle->Information[i].ObjType==0x1c||
                        pHandle->Information[i].ObjType==0x1a)
                {
                        strTmp.Format("PID:%d/Addr:0x%08X(socket)/Handle:%d/\n",pHandle->Information[i].dwPid,
                        pHandle->Information[i].dwKeObject,pHandle->Information[i].HndlOffset);
                        HANDLE hTmp=NULL;
                        HANDLE srcFartherHandle=OpenProcess(WRITE_DAC,FALSE,pHandle->Information[i].dwPid);
                        if(srcFartherHandle!=NULL)
                        {
                                AdjustDacl(srcFartherHandle);
                                srcFartherHandle=OpenProcess(PROCESS_DUP_HANDLE,true,pHandle->Information[i].dwPid);
                                if(srcFartherHandle==NULL)
                                        continue;
                                HANDLE desFartherHandle=GetCurrentProcess();
                                DuplicateHandle(srcFartherHandle,(HANDLE)pHandle->Information[i].HndlOffset,desFartherHandle,&hTmp,
                                        STANDARD_RIGHTS_REQUIRED,true,0);

                                if(hTmp==NULL)
                                {
                                        CloseHandle(srcFartherHandle);
                                        continue;
                                }
                                sockaddr_in name = {0};
                                name.sin_family=AF_INET;
                                int namelen=sizeof(sockaddr_in);
                                SOCKET s=(SOCKET)hTmp;
                                int iRet =getsockname(s,(sockaddr*)&name,&namelen);
                                if ( iRet != SOCKET_ERROR )
                                {
                                        int sockType = 0;
                                        int optlen = 4;
                                        iRet = getsockopt( s, SOL_SOCKET, SO_TYPE, (char*)&sockType, &optlen );
                                        //+++++++++++ 显示Socket的进程ID、端口、类型、目的IP和端口 ++++++++++++
                                        sockaddr_in peername = {0};
                                        int peernamelen = sizeof(sockaddr_in);
                                        iRet = getpeername(s,(sockaddr*)&peername, &peernamelen );
                                       
                                        char szSocket[64];
                                        sprintf( szSocket, "PID=%4d PORT=%5d %d DestIP=%s:%d",
                                                pHandle->Information[i].dwPid, ntohs(name.sin_port),sockType,
                                                inet_ntoa( peername.sin_addr ) , ntohs(peername.sin_port));
                                        strTmp+=szSocket;
                                        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                                }
                                else
                                {
                                        CString strErr;
                                        strErr.Format("err getsockname %d",WSAGetLastError());
                                        strTmp+=strErr;
                                }
                        }
                }else
                        strTmp.Format("PID:%d/Addr:0x%08X/Handle:%d\n",pHandle->Information[i].dwPid,
                                pHandle->Information[i].dwKeObject,pHandle->Information[i].HndlOffset);

                int iCountItems=m_ListLog.GetItemCount();
                strTmp1.Format("%d",i);
                m_ListLog.InsertItem(iCountItems,strTmp1);
                m_ListLog.SetItemText(iCountItems,1,strTmp);
        }
        if(buf!=NULL)
        {
                free(buf);
                buf=NULL;
        }
        return;

4.其中用到的全局函数
//提权
BOOL EnablePrivilege(char *privilegeName)
{       
        HANDLE hToken=NULL;
        HANDLE hCurrent=GetCurrentProcess();
        if(0==(int)hCurrent)
                return FALSE;
        if (!OpenProcessToken(hCurrent,
                TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
                &hToken))
        {
                return FALSE;
        }
       
        TOKEN_PRIVILEGES tkp;
       
        LookupPrivilegeValue(NULL, privilegeName , &tkp.Privileges[0].Luid);
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
       
        AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0);
       
        BOOL bEnabled = (GetLastError() == ERROR_SUCCESS);
       
        CloseHandle(hToken);
        return bEnabled;
}
//转换安全表
void AdjustDacl( HANDLE hProcess )
{
        SID world={SID_REVISION,1,SECURITY_WORLD_SID_AUTHORITY,0};
        LPTSTR ptstrName=(LPTSTR)&world;
        EXPLICIT_ACCESS ea=
        {STANDARD_RIGHTS_ALL|SPECIFIC_RIGHTS_ALL,
                SET_ACCESS,NO_INHERITANCE,
                {0,NO_MULTIPLE_TRUSTEE,TRUSTEE_IS_SID,
                TRUSTEE_IS_USER,ptstrName}};
        ACL *pdacl=0;
        SetEntriesInAcl(1,&ea,0,&pdacl);
        SetSecurityInfo(hProcess,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,0,0,pdacl,0);
        LocalFree(pdacl);
}

以上代码获取句柄没有问题可是碰到对应关系就丑大了。

运行结果在附件里面,附件里面还有一个应用程序是微软自己开发的,它可以完成端口进程的监控,因为使用了大量的隐藏api,本人的逆向又不是很强,所以无法分析到结果,如果大牛想看看,可以逆向一下。谢谢。

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

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (7)
雪    币: 56
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Sketcher 2009-12-17 18:48
2
0
XP: AllocateAndGetTcpExTableFromStack()
Vista: InternalGetTcpTable2   InternalGetUdpTableWithOwnerPid

Win7不知道上面的还能用不,貌似是不能了...
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
xacker 1 2009-12-17 20:35
3
0
可以用哦  3层函数 MS 都是向下兼容的
雪    币: 232
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
maccoray 2 2009-12-18 10:09
4
0
Sketcher先生,我也看到InternalGetTcpTable2,InternalGetUdpTableWithOwnerPid这两个函数在win7里面有使用到,好像是在netstat这个命令行可运行文件里面调用到,但是他没有具体文档,是否能提供一个范例,教教我如何使用这两个函数呢?不胜感激。
xacker先生,您说的可以用3层都兼容,但似乎AllocateAndGetTcpExTableFromStack函数真的是不能正常使用了,似乎这样未公开的函数,微软根本不会为它们的兼容性买单。如果真的能够使用,能否详细说明一下环境,设置,以及如何调用,不胜感激。
雪    币: 56
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Sketcher 2009-12-18 12:54
5
0
//Netstat -anb

#pragma once
#pragma once
#include <Windows.h>
#include <Psapi.h>
#include <Iprtrmib.h>
#pragma  comment(lib,"Iphlpapi.Lib")
#pragma  comment(lib,"Psapi.lib")
#pragma  comment(lib,"WS2_32.lib")

typedef struct{
        DWORD dwState;      //连接状态
        DWORD dwLocalAddr;  //本地地址
        DWORD dwLocalPort;  //本地端口
        DWORD dwRemoteAddr; //远程地址
        DWORD dwRemotePort; //远程端口
        DWORD dwProcessId;  //进程标识
}MIB_TCPEXROW,*PMIB_TCPEXROW;

typedef struct{
        DWORD dwLocalAddr;  //本地地址
        DWORD dwLocalPort;  //本地端口
        DWORD dwProcessId;  //进程标识
}MIB_UDPEXROW,*PMIB_UDPEXROW;

typedef struct{
        DWORD dwState;      //连接状态
        DWORD dwLocalAddr;  //本地地址
        DWORD dwLocalPort;  //本地端口
        DWORD dwRemoteAddr; //远程地址
        DWORD dwRemotePort; //远程端口
        DWORD dwProcessId;  //进程标识
        DWORD Unknown;      //待定标识
}MIB_TCPEXROW_VISTA,*PMIB_TCPEXROW_VISTA;

typedef struct{
        DWORD dwNumEntries;
        MIB_TCPEXROW table[ANY_SIZE];
}MIB_TCPEXTABLE,*PMIB_TCPEXTABLE;

typedef struct{
        DWORD dwNumEntries;
        MIB_TCPEXROW_VISTA table[ANY_SIZE];
}MIB_TCPEXTABLE_VISTA,*PMIB_TCPEXTABLE_VISTA;

typedef struct{
        DWORD dwNumEntries;
        MIB_UDPEXROW table[ANY_SIZE];
}MIB_UDPEXTABLE,*PMIB_UDPEXTABLE;

//enum OSVersion {XP,VISTA,OTHER};

typedef DWORD (WINAPI *PFNAllocateAndGetTcpExTableFromStack)(
        PMIB_TCPEXTABLE *pTcpTabel,
        bool bOrder,
        HANDLE heap,
        DWORD zero,
        DWORD flags
        );

typedef DWORD (WINAPI *PFNAllocateAndGetUdpExTableFromStack)(
        PMIB_UDPEXTABLE *pUdpTable,
        bool bOrder,
        HANDLE heap,
        DWORD zero,
        DWORD flags
        );

typedef DWORD (WINAPI *_InternalGetTcpTable2)(
        PMIB_TCPEXTABLE_VISTA *pTcpTable_Vista,
        HANDLE heap,
        DWORD flags
        );

typedef DWORD (WINAPI *_InternalGetUdpTableWithOwnerPid)(
        PMIB_UDPEXTABLE *pUdpTable,
        HANDLE heap,
        DWORD flags
        );

//************************************
// Method:    GetProcInfo
// FullName:  GetProcInfo
// Access:    public
// Returns:   DWORD         if success,return PID;else,return -1
// Qualifier:
// Parameter: DWORD type UDP==0 TCP==1
// Parameter: DWORD port
// Parameter: LPCTSTR lpExeName
// Parameter: LPCTSTR lpExePath
//************************************
DWORD GetProcInfo(BOOL type,DWORD port,LPWSTR lpExeName,LPWSTR lpExePath)
{
        HMODULE hModule = LoadLibrary(L"iphlpapi.dll");
        if (hModule == NULL)
                return -1;

        if (type)
        {
                //声明未文档函数
                PFNAllocateAndGetTcpExTableFromStack pAllcoteAndGetTcpExTableFromStack;
                pAllcoteAndGetTcpExTableFromStack = (PFNAllocateAndGetTcpExTableFromStack)GetProcAddress(hModule,"AllocateAndGetTcpExTableFromStack");
                if (pAllcoteAndGetTcpExTableFromStack != NULL)
                {
                        PMIB_TCPEXTABLE pTcpExTable;
                        if (pAllcoteAndGetTcpExTableFromStack(&pTcpExTable,TRUE,GetProcessHeap(),2,2) != 0)
                                return -1;

                        for (UINT i=0;i<pTcpExTable->dwNumEntries;i++)
                        {
                                int temp = ntohs(0x0000FFFF&pTcpExTable->table[i].dwLocalPort);
                                if (port == temp)
                                {
                                        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,pTcpExTable->table[i].dwProcessId);
                                        GetModuleBaseName(hProcess,NULL,lpExeName,MAX_PATH);
                                        GetModuleFileNameEx(hProcess,NULL,lpExePath,MAX_PATH);
                                       
                                        return pTcpExTable->table[i].dwProcessId;
                                }
                        }
                       
                        return -1;
                }
                else
                {
                        PMIB_TCPEXTABLE_VISTA pTcpTable_Vista;
                        _InternalGetTcpTable2 pGetTcpTable = (_InternalGetTcpTable2)GetProcAddress(hModule,"InternalGetTcpTable2");
                        if (pGetTcpTable == NULL)
                                return -1;

                        if (pGetTcpTable(&pTcpTable_Vista,GetProcessHeap(),1))
                                return -1;

                        for (UINT i=0;i<pTcpTable_Vista->dwNumEntries;i++)
                        {
                                if (port == pTcpTable_Vista->table[i] .dwLocalPort)
                                {
                                        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,pTcpTable_Vista->table[i].dwProcessId);
                                        GetModuleBaseName(hProcess,NULL,lpExeName,MAX_PATH);
                                        GetModuleFileNameEx(hProcess,NULL,lpExePath,MAX_PATH);

                                        return pTcpTable_Vista->table[i].dwProcessId;
                                }
                        }

                        return -1;       
                }

        }
        else
        {
                //声明未文档函数
                //UDP端口信息结构体
                PMIB_UDPEXTABLE pUdpExTable;
                PFNAllocateAndGetUdpExTableFromStack pAllcoteAndGetUdpExTableFromStack;
                pAllcoteAndGetUdpExTableFromStack = (PFNAllocateAndGetUdpExTableFromStack)GetProcAddress(hModule,"AllocateAndGetUdpExTableFromStack");
                if (pAllcoteAndGetUdpExTableFromStack != NULL)
                {
                        if (pAllcoteAndGetUdpExTableFromStack(&pUdpExTable,TRUE,GetProcessHeap(),2,2) != 0)
                                return -1;

                        for (UINT i=0;i<pUdpExTable->dwNumEntries;i++)
                        {
                                if (port == ntohs(0x0000FFFF&pUdpExTable->table[i].dwLocalPort))
                                {
                                        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,pUdpExTable->table[i].dwProcessId);
                                        GetModuleBaseName(hProcess,NULL,lpExeName,MAX_PATH);
                                        GetModuleFileNameEx(hProcess,NULL,lpExePath,MAX_PATH);

                                        return pUdpExTable->table[i].dwProcessId;
                                }
                        }

                        return -1;
                }
                else
                {
                        _InternalGetUdpTableWithOwnerPid pGetUdpTable;
                        pGetUdpTable = (_InternalGetUdpTableWithOwnerPid)GetProcAddress(hModule,"InternalGetUdpTableWithOwnerPid");
                        if (pGetUdpTable != NULL)
                        {
                                if (pGetUdpTable(&pUdpExTable,GetProcessHeap(),1))
                                        return -1;

                                for (UINT i=0;i<pUdpExTable->dwNumEntries;i++)
                                {
                                        if (port == pUdpExTable->table[i].dwLocalPort)
                                        {
                                                HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,pUdpExTable->table[i].dwProcessId);
                                                GetModuleBaseName(hProcess,NULL,lpExeName,MAX_PATH);
                                                GetModuleFileNameEx(hProcess,NULL,lpExePath,MAX_PATH);

                                                return pUdpExTable->table[i].dwProcessId;
                                        }
                                }
                        }

                        return -1;
                }
        }
}

int main()
{
        WCHAR szExeName[MAX_PATH] = {0};
        WCHAR szExePath[MAX_PATH] = {0};
        int type,port;
        cout<<"TCP==1 UDP==0"<<endl
                <<"Protocol:";
        cin>>type;
        cout<<"Port:";cin>>port;

        DWORD dwPid = GetProcInfo(type,port,szExeName,szExePath);
        if (dwPid != -1)
        {
                wcout<<dwPid<<"\t"<<szExeName<<"\t"<<szExePath<<endl;
        }
        else
        {
                cout<<"Error!"<<endl;
        }

        return 0;
}
雪    币: 56
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Sketcher 2009-12-18 12:55
6
0
不知道Win7下好使不...试下顺便跟俺说下哈。
雪    币: 232
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
maccoray 2 2009-12-21 10:07
7
0
Sketcher先生,谢谢你,测试是成功的,可以获取对应关系,测试环境环境如下:
os:win7旗舰版
IDE:vc6.0
SDK:Microsoft Platform SDK for Windows XP SP2
雪    币: 56
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Sketcher 2009-12-21 22:56
8
0
客气客气,谢谢你帮俺测试老..啊哈哈。
游客
登录 | 注册 方可回帖
返回