|
📌查看exe基本信息需要反编译的exe查看exe文件的打包工具,查看exe信息的软件叫DetectItEasy(查壳工具)由图我们可以看出当前选中的exe文件是由名叫PyInstaller的打包工具打包好的exe📌反编译exe反编译工具:pyinstxtractor.py🔑使用方法pythonpyinstxtractor.pyXXXXX.exe反编译工具内容,读者只需要将其复制粘贴即可用,并命名为pyinstxtractor.py💻代码"""PyInstallerExtractorv2.0(Supportspyinstaller6.3.0,6.2.0,6.1.0,6.0.0,5.13.2,5.13.1,5.13.0,5.12.0,5.11.0,5.10.1,5.10.0,5.9.0,5.8.0,5.7.0,5.6.2,5.6.1,5.6,5.5,5.4.1,5.4,5.3,5.2,5.1,5.0.1,5.0,4.10,4.9,4.8,4.7,4.6,4.5.1,4.5,4.4,4.3,4.2,4.1,4.0,3.6,3.5,3.4,3.3,3.2,3.1,3.0,2.1,2.0)Author:ExtremeCodersE-mail:extremecoders(at)hotmail(dot)comWeb:https://0xec.blogspot.comDate:26-March-2020Url:https://github.com/extremecoders-re/pyinstxtractorForanysuggestions,leaveacommentonhttps://forum.tuts4you.com/topic/34455-pyinstaller-extractor/Thisscriptextractsapyinstallergeneratedexecutablefile.Pyinstallerinstallationisnotneeded.Thescripthasitall.Forbestresults,itisrecommendedtorunthisscriptinthesameversionofpythonaswasusedtocreatetheexecutable.Thisisjusttopreventunmarshallingerrors(ifany)whileextractingthePYZarchive.Usage:JustcopythisscripttothedirectorywhereyourexeresidesandrunthescriptwiththeexefilenameasaparameterC:\\path\\to\\exe\\>pythonpyinstxtractor.py$/path/to/exe/pythonpyinstxtractor.pyLicensedunderGNUGeneralPublicLicense(GPL)v3.Youarefreetomodifythissource.CHANGELOG================================================Version1.1(Jan28,2014)--------------------------------------------------FirstRelease-Supportsonlypyinstaller2.0Version1.2(Sept12,2015)--------------------------------------------------Addedsupportforpyinstaller2.1and3.0dev-Cleanedupcode-Scriptisnowmoreverbose-Executableextractedwithinadedicatedsub-directory(Supportforpyinstaller3.0devisexperimental)Version1.3(Dec12,2015)--------------------------------------------------Addedsupportforpyinstaller3.0final-Scriptiscompatiblewithbothpython2.x&3.x(ThankstoMoritzKroll@AviraOperationsGmbH&Co.KG)Version1.4(Jan19,2016)--------------------------------------------------Fixedabugwhenwritingpycfiles>=version3.3(ThankstoDanielloAlto:https://github.com/Djamana)Version1.5(March1,2016)--------------------------------------------------Addedsupportforpyinstaller3.1(ThankstoBerwynHoytforreporting)Version1.6(Sept5,2016)--------------------------------------------------Addedsupportforpyinstaller3.2-Extractorwillusearandomnamewhileextractingunnamedfiles.-Forencryptedpyzarchivesitwilldumpthecontentsasis.Previously,thetoolwouldfail.Version1.7(March13,2017)--------------------------------------------------Madethescriptcompatiblewithpython2.6(ThankstoRossforreporting)Version1.8(April28,2017)--------------------------------------------------Supportforsub-directoriesin.pyzfiles(ThankstoMoritzKroll@AviraOperationsGmbH&Co.KG)Version1.9(November29,2017)--------------------------------------------------Addedsupportforpyinstaller3.3-Displaythescriptswhicharerunatentry(ThankstoMichaelGillespie@malwarehunterteamforthefeaturerequest)Version2.0(March26,2020)--------------------------------------------------Projectmigratedtogithub-Supportspyinstaller3.6-AddedsupportforPython3.7,3.8-Theheaderofallextractedpyc'sarenowautomaticallyfixed"""from__future__importprint_functionimportosimportstructimportmarshalimportzlibimportsysfromuuidimportuuid4asuniquenameclassCTOCEntry:def__init__(self,position,cmprsdDataSize,uncmprsdDataSize,cmprsFlag,typeCmprsData,name):self.position=positionself.cmprsdDataSize=cmprsdDataSizeself.uncmprsdDataSize=uncmprsdDataSizeself.cmprsFlag=cmprsFlagself.typeCmprsData=typeCmprsDataself.name=nameclassPyInstArchiveYINST20_COOKIE_SIZE=24#Forpyinstaller2.0PYINST21_COOKIE_SIZE=24+64#Forpyinstaller2.1+MAGIC=b'MEI\014\013\012\013\016'#Magicnumberwhichidentifiespyinstallerdef__init__(self,path):self.filePath=pathself.pycMagic=b'\0'*4self.barePycList=[]#Listofpyc'swhoseheadershavetobefixeddefopen(self):try:self.fPtr=open(self.filePath,'rb')self.fileSize=os.stat(self.filePath).st_sizeexcept:print('[!]Error:Couldnotopen{0}'.format(self.filePath))returnFalsereturnTruedefclose(self):try:self.fPtr.close()except:passdefcheckFile(self):print('[+]Processing{0}'.format(self.filePath))searchChunkSize=8192endPos=self.fileSizeself.cookiePos=-1ifendPos=searchChunkSizeelse0chunkSize=endPos-startPosifchunkSize=100else(pyver//10,pyver%10)print('[+]Pythonversion:{0}.{1}'.format(self.pymaj,self.pymin))#AdditionaldataafterthecookietailBytes=self.fileSize-self.cookiePos-(self.PYINST20_COOKIE_SIZEifself.pyinstVer==20elseself.PYINST21_COOKIE_SIZE)#OverlayisthedataappendedattheendofthePEself.overlaySize=lengthofPackage+tailBytesself.overlayPos=self.fileSize-self.overlaySizeself.tableOfContentsPos=self.overlayPos+tocself.tableOfContentsSize=tocLenprint('[+]Lengthofpackage:{0}bytes'.format(lengthofPackage))returnTruedefparseTOC(self):#Gotothetableofcontentsself.fPtr.seek(self.tableOfContentsPos,os.SEEK_SET)self.tocList=[]parsedLen=0#ParsetableofcontentswhileparsedLenARCHIVE_ITEM_DEPENDENCY#o->ARCHIVE_ITEM_RUNTIME_OPTION#Theseareruntimeoptions,notfilescontinuebasePath=os.path.dirname(entry.name)ifbasePath!='':#Checkifpathexists,createifnotifnotos.path.exists(basePath)s.makedirs(basePath)ifentry.typeCmprsData==b's':#s->ARCHIVE_ITEM_PYSOURCE#Entrypointareexpectedtobepythonscriptsprint('[+]Possibleentrypoint:{0}.pyc'.format(entry.name))ifself.pycMagic==b'\0'*4:#ifwedon'thavethepycheaderyet,fixtheminalaterpassself.barePycList.append(entry.name+'.pyc')self._writePyc(entry.name+'.pyc',data)elifentry.typeCmprsData==b'M'orentry.typeCmprsData==b'm':#M->ARCHIVE_ITEM_PYPACKAGE#m->ARCHIVE_ITEM_PYMODULE#packagesandmodulesarepycfileswiththeirheaderintact#FromPyInstaller5.3andabovepycheadersarenolongerstored#https://github.com/pyinstaller/pyinstaller/commit/a97fdfifdata[2:4]==b'\r\n':#=pyinstaller5.3ifself.pycMagic==b'\0'*4:#ifwedon'thavethepycheaderyet,fixtheminalaterpassself.barePycList.append(entry.name+'.pyc')self._writePyc(entry.name+'.pyc',data)else:self._writeRawData(entry.name,data)ifentry.typeCmprsData==b'z'orentry.typeCmprsData==b'Z':self._extractPyz(entry.name)#Fixbarepyc'sifanyself._fixBarePycs()def_fixBarePycs(self):forpycFileinself.barePycList:withopen(pycFile,'r+b')aspycFile:#OverwritethefirstfourbytespycFile.write(self.pycMagic)def_writePyc(self,filename,data):withopen(filename,'wb')aspycFile:pycFile.write(self.pycMagic)#pycmagicifself.pymaj>=3andself.pymin>=7:#PEP552--DeterministicpycspycFile.write(b'\0'*4)#BitfieldpycFile.write(b'\0'*8)#(Timestamp+size)||hashelse:pycFile.write(b'\0'*4)#Timestampifself.pymaj>=3andself.pymin>=3:pycFile.write(b'\0'*4)#SizeparameteraddedinPython3.3pycFile.write(data)def_extractPyz(self,name):dirName=name+'_extracted'#Createadirectoryforthecontentsofthepyzifnotos.path.exists(dirName)s.mkdir(dirName)withopen(name,'rb')asf:pyzMagic=f.read(4)assertpyzMagic==b'PYZ\0'#SanityCheckpyzPycMagic=f.read(4)#Pythonmagicvalueifself.pycMagic==b'\0'*4:self.pycMagic=pyzPycMagicelifself.pycMagic!=pyzPycMagic:self.pycMagic=pyzPycMagicprint('[!]Warning:pycmagicoffilesinsidePYZarchivearedifferentfromthoseinCArchive')#SkipPYZextractionifnotrunningunderthesamepythonversionifself.pymaj!=sys.version_info.majororself.pymin!=sys.version_info.minor:print('[!]Warning:ThisscriptisrunninginadifferentPythonversionthantheoneusedtobuildtheexecutable.')print('[!]PleaserunthisscriptinPython{0}.{1}topreventextractionerrorsduringunmarshalling'.format(self.pymaj,self.pymin))print('[!]Skippingpyzextraction')return(tocPosition,)=struct.unpack('!i',f.read(4))f.seek(tocPosition,os.SEEK_SET)try:toc=marshal.load(f)except:print('[!]UnmarshallingFAILED.Cannotextract{0}.Extractingremainingfiles.'.format(name))returnprint('[+]Found{0}filesinPYZarchive'.format(len(toc)))#Frompyinstaller3.1+tocisalistoftuplesiftype(toc)==list:toc=dict(toc)forkeyintoc.keys()ispkg,pos,length)=toc[key]f.seek(pos,os.SEEK_SET)fileName=keytry:#forPython>3.3somekeysarebytesobjectsomearestrobjectfileName=fileName.decode('utf-8')except:pass#PreventwritingoutsidedirNamefileName=fileName.replace('..','__').replace('.',os.path.sep)ifispkg==1:filePath=os.path.join(dirName,fileName,'__init__.pyc')else:filePath=os.path.join(dirName,fileName+'.pyc')fileDir=os.path.dirname(filePath)ifnotos.path.exists(fileDir)s.makedirs(fileDir)try:data=f.read(length)data=zlib.decompress(data)except:print('[!]Error:Failedtodecompress{0},probablyencrypted.Extractingasis.'.format(filePath))open(filePath+'.encrypted','wb').write(data)else:self._writePyc(filePath,data)defmain():iflen(sys.argv)')else:arch=PyInstArchive(sys.argv[1])ifarch.open():ifarch.checkFile():ifarch.getCArchiveInfo():arch.parseTOC()arch.extractFiles()arch.close()print('[+]Successfullyextractedpyinstallerarchive:{0}'.format(sys.argv[1]))print('')print('Youcannowuseapythondecompileronthepycfileswithintheextracteddirectory')returnarch.close()if__name__=='__main__':main()'运行运行反编译的结果为一个添加后缀_extracted的文件夹📌参考文献GitHub-horsicq/Detect-It-Easy:用于确定Windows、Linux和MacOS文件类型的程序。GitHub-extremecoders-re/pyinstxtractor:PyInstaller提取器超详细Pyinstaller打包exe+反编译Pyinstaller打包的exe教程+防止反编译教程-知乎(zhihu.com)
|
|