找回密码
 会员注册
查看: 16|回复: 0

Python解包及反编译PyInstallerExtractor+uncompyle6

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-9-9 20:12:13 | 显示全部楼层 |阅读模式
Python解包及反编译yInstallerExtractor+uncompyle6文章目录Python解包及反编译yInstallerExtractor+uncompyle6一、前言二、PyInstallerExtractor解包1、安装pyinstxtractor2、解包三、反编译uncompyle6工具使用1、pip安装uncompyle62、找到主文件并编译3、解压完成查看源码四、一键解包并编译一、前言有时候会遇到一些人制作一键安装包的时候会把一些程序封装进exe里面,但我们又想拿到里面源码的情况。在这里就涉及到了解包与反编译的。二、PyInstallerExtractor解包目前的python主流的打包方式是使用pyinstaller,针对这种情况可以使用pyinstallerExtractor进行解包。前提使用pyinstaller进行打包未加密1、安装pyinstxtractor新建一个py文件pyinstxtractor.py,然后将下面的内容拷贝进去然后就安装好了,要使用的时候与待解包的exe文件放在同一文件夹即可"""PyInstallerExtractorv2.0(Supportspyinstaller6.6.0,6.5.0,6.4.0,6.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()1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674682、解包在使用前:将需解包的exe与下载的pyinstxtractor.py存入同级文件夹使用命令行输入如下指令,得到exe的解包文件夹.pythonpyinstxtractor.py{exe路径}示例:pythonpyinstxtractor.pyCreatFoder.exe12运行结果:解包后文件放在以exe名字+_extracted的文件夹中三、反编译uncompyle6工具使用目前代码还不能用,打开会看到基本全是乱码。在这里需要对在线pyc,pyo,pyd文件等进行反编译成py文件1、pip安装uncompyle6pipinstalluncompyle612、找到主文件并编译主文件的命名一般与其他库不同,有比较明显的开发者个人特征,且后缀通常是pyc。找到之后再同级目录下输入命令行执行uncompyle6.exe{pyc文件}>{py文件输出路径}示例3、解压完成查看源码无乱码,一切正常四、一键解包并编译很多时候我们对于解包和编译是同一流程的。为了加快获取目标源码这一步骤,我将解包和编译的流程集中了起来,源码如下:新建一个py文件:pyinstxtractorV2.py"""PyInstallerExtractorv2.0(Supportspyinstaller6.6.0,6.5.0,6.4.0,6.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()importsubprocess,os,concurrent.futuresdefhandle(filePath):try:#定义要执行的命令command="uncompyle6{}>{}".format(filePath,filePath.replace('pyc','py'))#使用subprocess模块执行命令process=subprocess.Popen(command,shell=True)process.wait()#等待命令执行完成print(command)os.remove(filePath)returnTrueexceptExceptionase:print(e)returnFalsedefexcutor():print('检查是否已安装uncompyle6')#检查是否已安装uncompyle6try:subprocess.check_output(['uncompyle6','--version'])print("uncompyle6isalreadyinstalled.")except(subprocess.CalledProcessError,FileNotFoundError):print("uncompyle6isnotinstalled.Installing...")subprocess.call(['pip','install','uncompyle6'])currentPath=os.path.dirname(os.path.abspath(__file__))targe=os.path.basename(sys.argv[1])print('解包完成,开始反编译')targeDir=os.path.join(currentPath,targe+'_extracted')withconcurrent.futures.ThreadPoolExecutor(max_workers=8)asexcutor:futures=[]forroot,dirs,filesinos.walk(targeDir):forfileinfiles:filePath=os.path.join(root,file)iffilePath.endswith('pyc'):task=excutor.submit(handle,filePath)futures.append(task)forfutureinconcurrent.futures.as_completed(futures):ret=future.result()if__name__=='__main__':main()excutor()123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505使用将pyinstxtractorV2.py文件与待处理的exe文件放置在同一目录并执行:示例:python.\pyinstxtractorV2.py.\manager232.exe
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-9 06:01 , Processed in 0.533132 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表