21.1 Python 使用PEfile分析PE文件

这篇具有很好参考价值的文章主要介绍了21.1 Python 使用PEfile分析PE文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

PeFile模块是Python中一个强大的便携式第三方PE格式分析工具,用于解析和处理Windows可执行文件。该模块提供了一系列的API接口,使得用户可以通过Python脚本来读取和分析PE文件的结构,包括文件头、节表、导入表、导出表、资源表、重定位表等等。此外,PEfile模块还可以帮助用户进行一些恶意代码分析,比如提取样本中的字符串、获取函数列表、重构导入表、反混淆等等。PEfile模块是Python中处理PE文件的重要工具之一,广泛应用于二进制分析、安全研究和软件逆向工程等领域。

由于该模块为第三方模块,在使用之前读者需要在命令行下执行pip install pefile命令安装第三方库,当安装成功后即可正常使用,如下所示则是该模块的基本使用方法,读者可自行学习理解。

21.1.1 打开并加载PE文件

如下这段代码封装并实现了OpenPeFile函数,可用于打开一个PE文件,在其内部首先判断了可执行文件是否被压缩如果被压缩则会通过zipfile模块将压缩包读入内存并调用C2BIP3函数将数据集转换为2字节,接着再执行pefile.PE()函数,该函数可用于将可执行文件载入,至此读者可在主函数内通过pe.dump_dict()的方式输出该PE文件的所有参数,由于输出的是字典,读者可以使用字典与列表的方式灵活的提取出该程序的所有参数信息。

import sys
import zipfile
import pefile

# 如果是Python3则转换为2字节
def C2BIP3(string):
    if sys.version_info[0] > 2:
        return bytes([ord(x) for x in string])
    else:
        return string

# 打开文件
def OpenPeFile(filename):

    # 判断是否是ZIP压缩包
    if filename.lower().endswith('.zip'):
        try:
            oZipfile = zipfile.ZipFile(filename, 'r')
            file = oZipfile.open(oZipfile.infolist()[0], 'r', C2BIP3('infected'))
        except Exception:
            print(sys.exc_info()[1])
            sys.exit()
        oPE = pefile.PE(data=file.read())
        file.close()
        oZipfile.close()

    # 如果是空则
    elif filename == '':
        oPE = False
        return oPE
    # 否则直接打开文件
    else:
        oPE = pefile.PE(filename)
    return oPE

if __name__ == "__main__":
    pe = OpenPeFile("d://lyshark.exe")
    print(pe.FILE_HEADER.dump())
    print(pe.dump_dict())

21.1.2 解析PE头部数据

如下代码实现了解析PE结构中头部基本数据,在GetHeader函数内,我们首先通过pe.FILE_HEADER.Machine成员判断当前读入的文件的位数信息,通过pe.FILE_HEADER.Characteristics可判断PE文件的类型,通常为EXE可执行文件或DLL动态链接库文件,通过AddressOfEntryPoint加上ImageBase则可获取到程序的实际装载地址,压缩数据的计算可通过hashlib模块对PE文件字节数据进行计算摘要获取,最后是附加数据,通过get_overlay_data_start_offset则可获取到,并依次循环即可输出所有附加数据。

import hashlib
import pefile

# 计算得到数据长度,自动使用推荐大小
def NumberOfBytesHumanRepresentation(value):
    if value <= 1024:
        return '%s bytes' % value
    elif value < 1024 * 1024:
        return '%.1f KB' % (float(value) / 1024.0)
    elif value < 1024 * 1024 * 1024:
        return '%.1f MB' % (float(value) / 1024.0 / 1024.0)
    else:
        return '%.1f GB' % (float(value) / 1024.0 / 1024.0 / 1024.0)

# 获取PE头部基本信息
def GetHeader(pe):
    raw = pe.write()

    # 扫描基本信息
    print("-" * 50)
    print("程序基本信息")
    print("-" * 50)
    if (hex(pe.FILE_HEADER.Machine) == "0x14c"):
        print("程序位数: {}".format("x86"))
    if (hex(pe.FILE_HEADER.Machine) == "0x8664"):
        print("程序位数: {}".format("x64"))

    if (hex(pe.FILE_HEADER.Characteristics) == "0x102"):
        print("程序类型: Executable")
    elif (hex(pe.FILE_HEADER.Characteristics) == "0x2102"):
        print("程序类型: Dynamic link library")

    if pe.OPTIONAL_HEADER.AddressOfEntryPoint:
        oep = pe.OPTIONAL_HEADER.AddressOfEntryPoint + pe.OPTIONAL_HEADER.ImageBase
        print("实际入口: {}".format(hex(oep)))

    print("映像基址: {}".format(hex(pe.OPTIONAL_HEADER.ImageBase)))
    print("虚拟入口: {}".format(hex(pe.OPTIONAL_HEADER.AddressOfEntryPoint)))
    print("映像大小: {}".format(hex(pe.OPTIONAL_HEADER.SizeOfImage)))
    print("区段对齐: {}".format(hex(pe.OPTIONAL_HEADER.SectionAlignment)))
    print("文件对齐: {}".format(hex(pe.OPTIONAL_HEADER.FileAlignment)))
    print("区块数量: {}".format(int(pe.FILE_HEADER.NumberOfSections + 1)))
    print('熵值比例: %f (Min=0.0, Max=8.0)' % pe.sections[0].entropy_H(raw))

    # 计算压缩数据
    print("-" * 50)
    print("计算压缩数据")
    print("-" * 50)
    print('MD5     : %s' % hashlib.md5(raw).hexdigest())
    print('SHA-1   : %s' % hashlib.sha1(raw).hexdigest())
    print('SHA-256 : %s' % hashlib.sha256(raw).hexdigest())
    print('SHA-512 : %s' % hashlib.sha512(raw).hexdigest())

    # 扫描文件末尾是否存在附加数据
    print("-" * 50)
    print("扫描附加数据")
    print("-" * 50)
    overlayOffset = pe.get_overlay_data_start_offset()
    if overlayOffset != None:
        print("起始文件位置: 0x%08x"%overlayOffset)
        overlaySize = len(raw[overlayOffset:])
        print("长度: 0x%08x %s %.2f%%"%(overlaySize, NumberOfBytesHumanRepresentation(overlaySize), float(overlaySize) / float(len(raw)) * 100.0))
        print("MD5: %s" %hashlib.md5(raw[overlayOffset:]).hexdigest())
        print("SHA-256: %s" %hashlib.sha256(raw[overlayOffset:]).hexdigest())

if __name__ == "__main__":
    pe = pefile.PE("d://lyshark.exe")
    GetHeader(pe)

21.1.3 解析节表数据

运用PEFile模块解析节表也很容易,如下代码中分别实现了两个功能函数,函数ScanSection()用于输出当前文件的所有节表数据,其中通过pe.FILE_HEADER.NumberOfSections得到节表数量,并通过循环的方式依次解析pe.sections中的每一个节中元素,函数CheckSection()则可用于计算PE文件节大小以及节MD5值,完整代码如下所示;

import hashlib
import pefile

# 计算得到数据长度,自动使用推荐大小
def NumberOfBytesHumanRepresentation(value):
    if value <= 1024:
        return '%s bytes' % value
    elif value < 1024 * 1024:
        return '%.1f KB' % (float(value) / 1024.0)
    elif value < 1024 * 1024 * 1024:
        return '%.1f MB' % (float(value) / 1024.0 / 1024.0)
    else:
        return '%.1f GB' % (float(value) / 1024.0 / 1024.0 / 1024.0)

# 输出所有的节
def ScanSection(pe):
    print("-" * 100)
    print("{:10s}{:10s}{:10s}{:10s}{:10s}{:10s}{:10s}{:10s}".
          format("序号","节区名称","虚拟偏移","虚拟大小","实际偏移","实际大小","节区属性","熵值"))
    print("-" * 100)
    section_count = int(pe.FILE_HEADER.NumberOfSections + 1)

    for count,item in zip(range(1,section_count),pe.sections):
        print("%d\t\t\t%-10s\t0x%.8X\t0x%.8X\t0x%.8X\t0x%.8X\t0x%.8X\t%f"
              %(count,(item.Name).decode("utf-8"),item.VirtualAddress,item.Misc_VirtualSize,item.PointerToRawData,item.SizeOfRawData,item.Characteristics,item.get_entropy()))
    print("-" * 100)

# 计算所有节的MD5
def CheckSection(pe):
    print("-" * 100)
    print("序号\t\t节名称\t\t文件偏移\t\t大小\t\tMD5\t\t\t\t\t\t\t\t\t\t节大小")
    print("-" * 100)

    # 读取PE文件到内存
    image_data = pe.get_memory_mapped_image()

    section_count = int(pe.FILE_HEADER.NumberOfSections + 1)
    for count,item in zip(range(1,section_count),pe.sections):

        section_data = image_data[item.PointerToRawData: item.PointerToRawData + item.SizeOfRawData - 1]
        data_size = NumberOfBytesHumanRepresentation(len(section_data))
        hash_value = hashlib.md5(section_data).hexdigest()
        print("{}\t{:10s}\t{:10X}\t{:10X}\t{:30s}\t{}".format(count,(item.Name).decode("utf-8"),item.PointerToRawData,item.SizeOfRawData,hash_value,data_size))
    print("-" * 100)

if __name__ == "__main__":
    pe = pefile.PE("d://lyshark.exe")
    ScanSection(pe)
    CheckSection(pe)

21.1.4 节区RVA与FOA互转

此处计算节偏移地址,相信读者能理解,在之前的文章中我们详细的介绍了PE文件如何进行RVAFOA以及VA之间的转换的,如果是在平时的恶意代码分析中需要快速实现转换那么使用Python将是一个不错的选择,如下代码中RVAToFOA可将一个RVA相对地址转换为FOA文件偏移,FOAToRVA则可实现将一个FOA文件偏移转换为RVA先对地址,当然PeFile模块内也提供了get_rva_from_offset实现从FOA转RVA,get_offset_from_rva则是从RVA到FOA,读者可自行选择不同的转换方式。

import pefile

# 将RVA转换为FOA的函数
def RVAToFOA(pe,rva):
    for item in pe.sections:
        Section_Start = item.VirtualAddress
        Section_Ends = item.VirtualAddress + item.SizeOfRawData
        if rva >= Section_Start and rva < Section_Ends:
            return rva - item.VirtualAddress + item.PointerToRawData
    return -1

# 将FOA文件偏移转换为RVA相对地址
def FOAToRVA(pe,foa):
    ImageBase = pe.OPTIONAL_HEADER.ImageBase
    NumberOfSectionsCount = pe.FILE_HEADER.NumberOfSections

    for index in range(0,NumberOfSectionsCount):
        PointerRawStart = pe.sections[index].PointerToRawData
        PointerRawEnds = pe.sections[index].PointerToRawData + pe.sections[index].SizeOfRawData

        if foa >= PointerRawStart and foa <= PointerRawEnds:
            rva = pe.sections[index].VirtualAddress + (foa - pe.sections[index].PointerToRawData)
            return rva
    return -1

# 内部功能实现FOA->RVA互转
def inside(pe):
    # 从FOA获取RVA 传入十进制
    rva = pe.get_rva_from_offset(3952)
    print("对应内存RVA: {}".format(hex(rva)))

    # 从RVA获取FOA 传入十进制
    foa = pe.get_offset_from_rva(rva)
    print("对应文件FOA: {}".format(foa))

if __name__ == "__main__":
    pe = pefile.PE("d://lyshark.exe")
    ref = RVAToFOA(pe,4128)
    print("RVA转FOA => 输出十进制: {}".format(ref))

    ref = FOAToRVA(pe,1056)
    print("FOA转RVA => 输出十进制: {}".format(ref))

21.1.5 解析数据为Hex格式

如下代码片段实现了对PE文件的各种十六进制操作功能,封装cDump()类,该类内由多个类函数可以使用,其中HexDump()可用于将读入的PE文件以16进制方式输出,HexAsciiDump()则可用于输出十六进制以及所对应的ASCII格式,GetSectionHex()用于找到PE文件的.text节,并将此节内的数据读入到内存中,这段代码可以很好的实现对PE文件的十六进制输出与解析,读者可在实际开发中使用。

import pefile
from io import StringIO
import sys
import re

dumplinelength = 16

def CIC(expression):
    if callable(expression):
        return expression()
    else:
        return expression

def IFF(expression, valueTrue, valueFalse):
    if expression:
        return CIC(valueTrue)
    else:
        return CIC(valueFalse)

class cDump():
    def __init__(self, data, prefix='', offset=0, dumplinelength=16):
        self.data = data
        self.prefix = prefix
        self.offset = offset
        self.dumplinelength = dumplinelength

    # 输出指定位置的十六进制格式
    def HexDump(self):
        oDumpStream = self.cDumpStream(self.prefix)
        hexDump = ''
        for i, b in enumerate(self.data):
            if i % self.dumplinelength == 0 and hexDump != '':
                oDumpStream.Addline(hexDump)
                hexDump = ''
            hexDump += IFF(hexDump == '', '', ' ') + '%02X' % self.C2IIP2(b)
        oDumpStream.Addline(hexDump)
        return oDumpStream.Content()

    def CombineHexAscii(self, hexDump, asciiDump):
        if hexDump == '':
            return ''
        countSpaces = 3 * (self.dumplinelength - len(asciiDump))
        if len(asciiDump) <= self.dumplinelength / 2:
            countSpaces += 1
        return hexDump + '  ' + (' ' * countSpaces) + asciiDump

    # 输出指定位置的十六进制格式以及ASCII字符串
    def HexAsciiDump(self):
        oDumpStream = self.cDumpStream(self.prefix)
        hexDump = ''
        asciiDump = ''
        for i, b in enumerate(self.data):
            b = self.C2IIP2(b)
            if i % self.dumplinelength == 0:
                if hexDump != '':
                    oDumpStream.Addline(self.CombineHexAscii(hexDump, asciiDump))
                hexDump = '%08X:' % (i + self.offset)
                asciiDump = ''
            if i % self.dumplinelength == self.dumplinelength / 2:
                hexDump += ' '
            hexDump += ' %02X' % b
            asciiDump += IFF(b >= 32 and b <= 128, chr(b), '.')
        oDumpStream.Addline(self.CombineHexAscii(hexDump, asciiDump))
        return oDumpStream.Content()

    class cDumpStream():
        def __init__(self, prefix=''):
            self.oStringIO = StringIO()
            self.prefix = prefix

        def Addline(self, line):
            if line != '':
                self.oStringIO.write(self.prefix + line + '\n')

        def Content(self):
            return self.oStringIO.getvalue()

    @staticmethod
    def C2IIP2(data):
        if sys.version_info[0] > 2:
            return data
        else:
            return ord(data)

# 只输出十六进制数据
def HexDump(data):
    return cDump(data, dumplinelength=dumplinelength).HexDump()

# 输出十六进制与ASCII字符串
def HexAsciiDump(data):
    return cDump(data, dumplinelength=dumplinelength).HexAsciiDump()

# 找到指定节并读取hex数据
def GetSectionHex(pe):
    ImageBase = pe.OPTIONAL_HEADER.ImageBase
    for item in pe.sections:
        # 判断是否是.text节
        if str(item.Name.decode('UTF-8').strip(b'\x00'.decode())) == ".text":
            # print("虚拟地址: 0x%.8X 虚拟大小: 0x%.8X" %(item.VirtualAddress,item.Misc_VirtualSize))
            VirtualAddress = item.VirtualAddress
            VirtualSize = item.Misc_VirtualSize
            ActualOffset = item.PointerToRawData

            StartVA = hex(ImageBase + VirtualAddress)
            StopVA = hex(ImageBase + VirtualAddress + VirtualSize)
            print("[+] 代码段起始地址: {} 结束: {} 实际偏移:{} 长度: {}".format(StartVA, StopVA, ActualOffset, VirtualSize))

            # 获取到.text节区间内的数据
            hex_code = pe.write()[ActualOffset: VirtualSize]
            return hex_code
        else:
            print("程序中不存在.text节")
            return 0
    return 0

REGEX_STANDARD = '[\x09\x20-\x7E]'

def ExtractStringsASCII(data):
    regex = REGEX_STANDARD + '{%d,}'
    return re.findall(regex % 4, data)

def ExtractStringsUNICODE(data):
    regex = '((' + REGEX_STANDARD + '\x00){%d,})'
    return [foundunicodestring.replace('\x00', '') for foundunicodestring, dummy in re.findall(regex % 4, data)]

# 将传入Hex字符串以每16字符分割在一个列表内
def ExtractStrings(data):
    return ExtractStringsASCII(data) + ExtractStringsUNICODE(data)

if __name__ == "__main__":
    pe = pefile.PE("d://lyshark.exe")

    # 得到.text节内数据
    ref = GetSectionHex(pe)

    # 转为十六进制格式
    dump_hex = HexDump(ref)
    print(dump_hex)

    # 打包为每16字符一个列表
    dump_list = ExtractStrings(dump_hex)

    print(dump_list)

21.1.6 解析数据目录表

数据目录表用于记录可执行文件的数据目录项在文件中的位置和大小。数据目录表共有16个条目,每个条目都对应着一个数据目录项,每个数据目录项都描述了可执行文件中某一部分的位置和大小。

数据目录表的解析可以使用pe.OPTIONAL_HEADER.NumberOfRvaAndSizes首先获取到数据目录表的个数,接着二通过循环个数依次解包OPTIONAL_HEADER.DATA_DIRECTORY里面的每一个列表,在循环列表时依次解包输出即可。

import pefile

# 将RVA转换为FOA的函数
def RVAToFOA(pe,rva):
    for item in pe.sections:
        Section_Start = item.VirtualAddress
        Section_Ends = item.VirtualAddress + item.SizeOfRawData
        if rva >= Section_Start and rva < Section_Ends:
            return rva - item.VirtualAddress + item.PointerToRawData
    return -1

# 扫描数据目录表
def ScanOptional(pe):
    optional_size = pe.OPTIONAL_HEADER.NumberOfRvaAndSizes
    print("数据目录表个数: {}".format(optional_size))

    print("-" * 100)
    print("编号 \t\t\t 目录RVA\t\t 目录FOA\t\t\t 长度\t\t 描述信息")
    print("-" * 100)

    for index in range(0,optional_size):
        va = int(pe.OPTIONAL_HEADER.DATA_DIRECTORY[index].VirtualAddress)
        print("%03d \t\t 0x%08X\t\t 0x%08X\t\t %08d \t\t"
              %(index,
                pe.OPTIONAL_HEADER.DATA_DIRECTORY[index].VirtualAddress,
                RVAToFOA(pe,va),
                pe.OPTIONAL_HEADER.DATA_DIRECTORY[index].Size
                ),end="")

        if index == 0:
            print("Export symbols")
        if index == 1:
            print("Import symbols")
        if index == 2:
            print("Resources")
        if index == 3:
            print("Exception")
        if index == 4:
            print("Security")
        if index == 5:
            print("Base relocation")
        if index == 6:
            print("Debug")
        if index == 7:
            print("Copyright string")
        if index == 8:
            print("Globalptr")
        if index == 9:
            print("Thread local storage (TLS)")
        if index == 10:
            print("Load configuration")
        if index == 11:
            print("Bound Import")
        if index == 12:
            print("Import Address Table")
        if index == 13:
            print("Delay Import")
        if index == 14:
            print("COM descriptor")
        if index == 15:
            print("NoUse")

if __name__ == "__main__":
    pe = pefile.PE("d://lyshark.exe")
    ScanOptional(pe)

21.1.7 解析导入导出表

导入表和导出表都是PE文件中的重要数据结构,分别记录着一个模块所导入和导出的函数和数据,如下所示则是使用PeFile模块实现对导入表与导出表的解析工作,对于导入表ScanImport的解析需要通过pe.DIRECTORY_ENTRY_IMPORT获取到完整的导入目录,并通过循环的方式输出x.imports中的数据即可,而对于导出表ScanExport则需要在pe.DIRECTORY_ENTRY_EXPORT.symbols导出符号中解析获取。文章来源地址https://www.toymoban.com/news/detail-711474.html

import pefile

# 输出所有导入表模块
def ScanImport(pe):
    print("-" * 100)
    try:
        for x in pe.DIRECTORY_ENTRY_IMPORT:
            for y in x.imports:
                print("[*] 模块名称: %-20s 导入函数: %-14s" %((x.dll).decode("utf-8"),(y.name).decode("utf-8")))
    except Exception:
        pass
    print("-" * 100)

# 输出所有导出表模块
def ScanExport(pe):
    print("-" * 100)
    try:
        for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
            print("[*] 导出序号: %-5s 模块地址: %-20s 模块名称: %-15s"
            %(exp.ordinal,hex(pe.OPTIONAL_HEADER.ImageBase + exp.address),(exp.name).decode("utf-8")))
    except:
        pass
    print("-" * 100)

if __name__ == "__main__":
    pe = pefile.PE("d://lyshark.exe")
    ScanImport(pe)
    ScanExport(pe)

到了这里,关于21.1 Python 使用PEfile分析PE文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FL Studio21.1中文完整版Win/Mac

    FL Studio All Plugins Edition【中文完整版 + Win/Mac】适合音乐制作人/工作室使用,全套插件!(20.9新增Vintage Chorus,Pitch Shifter变调插件)FL Studio是超多顶级音乐人的启蒙首选!包括百大DJ冠军Martin Garrix,六获格莱美提名的Deadmau5,现代嘻哈创始人TM88等等,名单每月都在增加!如果你

    2024年02月12日
    浏览(34)
  • IDEA(21.1终极版本)的安装教程及环境配置 Maven和(JDK)

    文章目录 Idea的安装及环境配置概要 安装流程 技术名词解释 技术细节 小结 提示:安装IDEA的地址(点击链接即可下载): https://download.jetbrains.com/idea/ideaIU-2021.1.3.exe 官网地址: IntelliJ IDEA – the Leading Java and Kotlin IDE IntelliJ IDEA is undoubtedly the top-choice IDE for software developers. It

    2024年03月12日
    浏览(81)
  • 21.3 Python 使用DPKT分析数据包

    dpkt项目是一个 Python 模块,主要用于对网络数据包进行解析和操作。它可以处理多种协议,例如 TCP 、 UDP 、 IP 等,并提供了一些常用的网络操作功能,例如计算校验和、解析 DNS 数据包等。由于其简单易用的特性, dpkt 被广泛应用于网络安全领域,例如流量分析、漏洞利用、

    2024年02月08日
    浏览(39)
  • PE文件反编译为python脚本流程

    DetectltEasy、PeiD查壳 常见打包工具PyInstaller,脱壳方法 (1)用pyinstxtractor.py脱壳,用”python pyinstxtractor.py 1.exe“命令,生成“.exe文件名_extracted” (2)用pyinstaller脱壳,之后可用pyi-archive_viewer +exe文件名查看 exe 内部的文件结构 下载:pip install pyinstaller 使用:pyinstaller 1.exe、

    2023年04月25日
    浏览(42)
  • 21 Python的datetime模块

    概述         在上一节,我们介绍了Python的time模块,包括:time模块中一些常用的属性和函数。在这一节,我们将介绍Python的datetime模块。datetime模块属于Python的内置模块,提供了一种方便的方法来处理日期和时间。该模块包含了许多类,包括:date、time、datetime、timedelta等

    2024年02月08日
    浏览(47)
  • 【头歌】——数据分析与实践-基于Python语言的文件与文件夹管理-文本 文件处理-利用csv模块进行csv文件的读写操作

    第1关 创建子文件夹 第2关 删除带有只读属性的文件 第3关 批量复制文件夹中的所有文件 未通过本题,如果您通过了本题欢迎补充到评论区,有时间我会整理进来 第1关 读取宋词文件,根据词人建立多个文件 第2关 读取宋词文件,并根据词人建立多个文件夹 第3关 读取宋词文

    2024年01月25日
    浏览(73)
  • Python 2.x 中如何使用pandas模块进行数据分析

    Python 2.x 中如何使用pandas模块进行数据分析 概述: 在数据分析和数据处理过程中,pandas是一个非常强大且常用的Python库。它提供了数据结构和数据分析工具,可以实现快速高效的数据处理和分析。本文将介绍如何在Python 2.x中使用pandas进行数据分析,并为读者提供一些代码示例

    2024年02月13日
    浏览(58)
  • 常用python代码大全-python使用csv模块进行CSV文件操作

    CSV文件是一种常见的数据存储格式,由逗号分隔的值组成。Python的csv模块提供了读取和写入CSV文件的功能。 以下是一个使用csv模块进行CSV文件操作的代码示例: 在上面的代码中,我们首先使用 open() 函数打开一个名为 example.csv 的CSV文件,并指定模式为 \\\'r\\\' ,表示只读模式。然

    2024年01月17日
    浏览(46)
  • macOS Monterey 12.6.5 (21G531) OC 0.9.1 / Cl 5151 / PE 三分区原版黑苹果镜像

     苹果近期发布了 macOS Big Sur 11.7.6 和 macOS Monterey 12.6.5 更新,本次更新重点修复了标记为 CVE-2023-28206 的漏洞,在 macOS 13.3.1 更新中已修复,推荐大家安装升级。 macOS Monterey 12.6.5 (21G531) 三分区原版黑苹果镜像 或文末置顶评论前往官网下载         本次更新重点修复了标记为

    2024年02月02日
    浏览(48)
  • 科普:python怎么使用Pyinstaller模块打包成可执行文件

    创建个虚拟环境来打包,以免把整个系统的乱七八糟的pip的都打包进去,建议每个项目创建对应的虚拟环境。 比如: conda create -n myenv python=3.10 PS:还需要安装项目依赖的其他模块,建议用requirements.txt文件安装 -h,–help 查看该模块的帮助信息 -F,-onefile 产生单个的可执行文

    2024年02月08日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包