def scanFunc(self,address): self.hcb.seek(address) if self.scan_flags[self.hcb.tell()]==1: return while 1: cur=self.hcb.tell() if cur>=self.codeBlockLen: break self.scan_flags[cur]=1 inst=self.hcb.readu8() if inst>0x27 or inst==0: int3() if inst==0xe: self.readstr() elif inst>7 or inst<2 or inst==3: self.hcb.seek(self.inst_len[inst],1) elif inst==2: to_addr=self.hcb.readu32() self.func.append(to_addr) self.scanFunc(to_addr) elif inst==4 or inst==5: return elif inst==7: to_addr=self.hcb.readu32() self.scanFunc(to_addr) elif inst==6: to_addr=self.hcb/readu32() self.scanFunc(to_addr) return
def scanFuncRecursive(self, address): self.hcb.seek(address) if self.scan_flags[self.hcb.tell()] == 1: return while 1: cur = self.hcb.tell() if cur >= self.codeBlockLen: break self.scan_flags[cur] = 1 inst = self.hcb.readu8() if inst > 0x27 or inst == 0: int3() if inst == 0xe: self.readstr() elif inst > 7 or inst < 2 or inst == 3: self.hcb.seek(self.inst_len[inst], 1) elif inst == 2: to_addr = self.hcb.readu32() self.func.append(to_addr) self.scanFuncRecursive(to_addr) elif inst == 4 or inst == 5: return elif inst == 7: to_addr = self.hcb.readu32() self.scanFuncRecursive(to_addr) elif inst == 6: to_addr = self.hcb.readu32() self.scanFuncRecursive(to_addr) return
def SplitPic(rgba): magic,bmp_size,off_bits=unpack('<hI4xI',rgba[0:14]) hdr_size, width, height, planes, bit_count=unpack('<IIiHH',rgba[14:30]) if bit_count!=32: #int3() return 0 w=width if height<0: h=-height else: h=height dib=rgba[off_bits:] if len(dib)<h*w*4: int3() return 0 rgb=bytearray(h*w*3) aph=bytearray(h*w) for i in range(h*w): rgb[i*3:i*3+3]=dib[i*4:i*4+3] aph[i]=dib[i*4+3] pallete=bytearray() for i in range(0x100): pallete+=pack('BBBB',i,i,i,0) bfa=pack('<2sIHHI',b'BM',len(aph)+0x36+len(pallete),0,0,0x36+len(pallete)) bia=pack('<IIiHH24s',0x28,w,height,1,8,b'\x00'*24) bmpa=bfa+bia+pallete+aph bfrgb=pack('<2sIHHI',b'BM',len(rgb)+0x36,0,0,0x36) birgb=pack('<IIiHH24s',0x28,w,height,1,24,b'\x00'*24) bmprgb=bfrgb+birgb+rgb return (bmprgb,bmpa)
def SplitPic(rgba): magic, bmp_size, off_bits = unpack('<hI4xI', rgba[0:14]) hdr_size, width, height, planes, bit_count = unpack('<IIiHH', rgba[14:30]) if bit_count != 32: #int3() return 0 w = width if height < 0: h = -height else: h = height dib = rgba[off_bits:] if len(dib) < h * w * 4: int3() return 0 rgb = bytearray(h * w * 3) aph = bytearray(h * w) for i in range(h * w): rgb[i * 3:i * 3 + 3] = dib[i * 4:i * 4 + 3] aph[i] = dib[i * 4 + 3] pallete = bytearray() for i in range(0x100): pallete += pack('BBBB', i, i, i, 0) bfa = pack('<2sIHHI', b'BM', len(aph) + 0x36 + len(pallete), 0, 0, 0x36 + len(pallete)) bia = pack('<IIiHH24s', 0x28, w, height, 1, 8, b'\x00' * 24) bmpa = bfa + bia + pallete + aph bfrgb = pack('<2sIHHI', b'BM', len(rgb) + 0x36, 0, 0, 0x36) birgb = pack('<IIiHH24s', 0x28, w, height, 1, 24, b'\x00' * 24) bmprgb = bfrgb + birgb + rgb return (bmprgb, bmpa)
def PackArc(fs,types,data,packf,names): if (len(types)!=len(data)) or (len(types)!=len(names))\ or (len(types)!=len(packf)): int3() itype=len(types) hdr=bytearray(pack('I',itype)) curpos=4+itype*12 for i in range(itype): hdr+=pack('4sII',types[i],len(data[i]),curpos) curpos+=len(data[i])*(G_strlen+8) data_start=curpos fs.seek(curpos) entry=bytearray() for i in range(itype): for j in range(len(data[i])): bf=packf[i](data[i][j]) entry+=names[i][j].encode('932').ljust(G_strlen,b'\0') entry+=pack('II',len(bf),curpos) fs.write(bf) curpos+=len(bf) fs.seek(0) if len(hdr)+len(entry)!=data_start: int3() fs.write(hdr) fs.write(entry)
def scanFunc2(self): self.hcb.seek(4) cur=self.hcb.tell() j=0 while cur<self.codeBlockLen: inst=self.hcb.readu8() if inst>0x27 or inst==0: print '%x'%self.hcb.tell() int3() if inst==1: addr=self.hcb.tell()-1 if addr not in self.func: self.func.append(addr) self.hcb.seek(2,1) elif inst==2: addr=self.hcb.readu32() if addr not in self.func: self.func.append(addr) elif inst==0xe: self.readstr() else: self.hcb.seek(self.inst_len[inst],1) cur=self.hcb.tell() if cur>=j*0x50000: print '%x/%x'%(cur,self.codeBlockLen) j+=1 self.func.append(self.codeBlockLen) self.func.sort()
def scanFunc2(self): self.hcb.seek(4) cur = self.hcb.tell() j = 0 while cur < self.codeBlockLen: inst = self.hcb.readu8() if inst > 0x27 or inst == 0: print('%x' % self.hcb.tell()) int3() if inst == 1: addr = self.hcb.tell()-1 if addr not in self.func: self.func.append(addr) self.hcb.seek(2, 1) elif inst == 2: addr = self.hcb.readu32() if addr not in self.func: self.func.append(addr) elif inst == 0xe: self.readstr() else: self.hcb.seek(self.inst_len[inst], 1) cur = self.hcb.tell() if cur >= j*0x50000: print('%x/%x' % (cur, self.codeBlockLen)) j += 1 self.func.append(self.codeBlockLen) self.func.sort()
def Parse(self): while self.vmcode.tell() < len(self.vmcode): self.text.append('%08X\t' % self.vmcode.tell()) self.code = self.vmcode.readu16() if self.code >= 0x800 and self.code <= 0x850: func = self.code800[self.code - 0x800] if func == 0: int3() func(self) elif self.code <= 0x1a9 and self.code >= 0x100: self.p10X() elif self.code >= 0x1b8 and self.code <= 0x200: self.p1BX() elif self.code >= 0x218 and self.code <= 0x260: self.p21X() elif self.code >= 0x270 and self.code <= 0x2c0: self.p27X() elif self.code >= 0x2d0 and self.code <= 0x320: self.p2DX() elif self.code <= 0x850: self.pLen8() else: int3() newt = [str(s) for s in self.text] return '\r\n'.join(newt)
def Parse(self): while self.vmcode.tell()<len(self.vmcode): self.text.append('%08X\t'%self.vmcode.tell()) self.code=self.vmcode.readu16() if self.code>=0x800 and self.code<=0x850: func=self.code800[self.code-0x800] if func==0: int3() func(self) elif self.code<=0x1a9 and self.code>=0x100: self.p10X() elif self.code>=0x1b8 and self.code<=0x200: self.p1BX() elif self.code>=0x218 and self.code<=0x260: self.p21X() elif self.code>=0x270 and self.code<=0x2c0: self.p27X() elif self.code>=0x2d0 and self.code<=0x320: self.p2DX() elif self.code<=0x850: self.pLen8() else: int3() newt=[str(s) for s in self.text] return '\r\n'.join(newt)
def Parse(self): self.codeBlockLen=self.hcb.readu32() self.hcb.seek(self.codeBlockLen) entry_point=self.hcb.readu32() self.hcb.seek(6,1) game_title=self.readstr() sysfunc_count=self.hcb.readu16() for i in range(sysfunc_count): self.hcb.seek(1,1) self.sysfunc.append(self.readstr()) print 'Scanning Funcs...' self.scanFunc2() print 'Parsing the script...' self.hcb.seek(4) cur=self.hcb.tell() func_it=0 j=0 while cur<self.codeBlockLen: if cur==self.func[func_it]: self.text.append('') if cur in self.funcNameTable: self.text.append('Func %s(%08X)'%(self.funcNameTable[cur].encode(self.codepage),cur)) else: self.text.append('Func #%04d(%08X)'%(func_it,cur)) func_it+=1 curline='%08X: '%cur inst=self.hcb.readu8() if inst==3: num=self.hcb.readu16() if num>=len(self.sysfunc): int3() curline+=self.mnemonics[inst]+' '+self.sysfunc[num] elif inst==2: addr=self.hcb.readu32() if addr in self.funcNameTable: curline+=self.mnemonics[inst]+' '+self.funcNameTable[addr].encode(self.codepage) else: curline+=self.mnemonics[inst]+' '+str(self.func.index(addr)) elif inst==0xe: curline+=(self.mnemonics[inst]+' '+self.readstr()) else: ilen=self.inst_len[inst] if ilen==0: opcode='' elif ilen==1: opcode=' %X'%self.hcb.readu8() elif ilen==2: opcode=' %X'%self.hcb.readu16() elif ilen==4: opcode=' %X'%self.hcb.readu32() curline+=(self.mnemonics[inst]+opcode) self.text.append(curline) cur=self.hcb.tell() if cur>=j*0x50000: print '%x/%x'%(cur,self.codeBlockLen) j+=1 return '\r\n'.join(self.text)
def GetStrs(stm, idx, txt, base): i = 0 int3() while i < len(stm): if stm[i] != 0: #print('\r%d'%len(txt)) idx.append(i + base) stm.seek(i) txt.append(stm.readstr().decode('932')) i = stm.tell() continue i += 1
def GetStrs(stm,idx,txt,base): i=0 int3() while i<len(stm): if stm[i]!=0: #print('\r%d'%len(txt)) idx.append(i+base) stm.seek(i) txt.append(stm.readstr().decode('932')) i=stm.tell() continue i+=1
def Parse(self): self.preProcess() print('Scanning Funcs...') self.scanFunc2() print('Parsing the script...') self.hcb.seek(4) cur = self.hcb.tell() func_it = 0 j = 0 while cur < self.codeBlockLen: if cur == self.func[func_it]: self.text.append('') if cur in self.funcNameTable: self.text.append('Func %s(%08X)' % (self.funcNameTable[cur], cur)) else: self.text.append('Func #%04d(%08X)' % (func_it, cur)) func_it += 1 curline = '%08X: ' % cur inst = self.hcb.readu8() if inst == 3: num = self.hcb.readu16() if num >= len(self.sysfunc): int3() curline += self.mnemonics[inst]+' '+self.sysfunc[num] elif inst == 2: addr = self.hcb.readu32() if addr in self.funcNameTable: curline += self.mnemonics[inst] + \ ' '+self.funcNameTable[addr] else: curline += self.mnemonics[inst] + \ ' '+str(self.func.index(addr)) elif inst == 0xe: curline += (self.mnemonics[inst]+' '+self.readstr()) else: ilen = self.inst_len[inst] if ilen == 0: opcode = '' elif ilen == 1: opcode = ' %X' % self.hcb.readu8() elif ilen == 2: opcode = ' %X' % self.hcb.readu16() elif ilen == 4: opcode = ' %X' % self.hcb.readu32() curline += (self.mnemonics[inst]+opcode) self.text.append(curline) cur = self.hcb.tell() if cur >= j*0x50000: print('%x/%x' % (cur, self.codeBlockLen)) j += 1 return '\r\n'.join(self.text)
def GetInt(self, l): if l < 0xd or l > 0x10: print('%x' % self.psb.tell()) int3() if l == 0xd: return self.psb.readu8() if l == 0xe: return self.psb.readu16() if l == 0xf: temp = self.psb.readu16() temp += self.psb.readu8() * 65536 return temp if l == 0x10: return self.psb.readu32()
def GetInt(psb, l): if l < 0xd or l > 0x10: print('%x' % psb.tell()) int3() if l == 0xd: return psb.readu8() if l == 0xe: return psb.readu16() if l == 0xf: temp = psb.readu16() temp += psb.readu8() * 65536 return temp if l == 0x10: return psb.readu32()
def GetInt(self,l): if l<0xd or l>0x10: print('%x'%self.psb.tell()) int3() if l==0xd: return self.psb.readu8() if l==0xe: return self.psb.readu16() if l==0xf: temp=self.psb.readu16() temp+=self.psb.readu8()*65536 return temp if l==0x10: return self.psb.readu32()
def GetInt(psb,l): if l<0xd or l>0x10: print('%x'%psb.tell()) int3() if l==0xd: return psb.readu8() if l==0xe: return psb.readu16() if l==0xf: temp=psb.readu16() temp+=psb.readu8()*65536 return temp if l==0x10: return psb.readu32()
def CombineDir(path1, path2): oris = os.listdir(path1) for pic in oris: if pic.rsplit('.', 1)[0].endswith('$'): continue if os.path.isdir(path1 + pic): if not os.path.exists(path2 + pic): os.makedirs(path2 + pic) inpics = os.listdir(path1 + pic) if pic + '$' not in oris: nomsk = 1 else: nomsk = 0 for ipic in inpics: rgbf = open(path1 + pic + '\\' + ipic, 'rb') if not nomsk: if not os.path.isfile(path1 + pic + '$\\' + ipic): continue af = open(path1 + pic + '$\\' + ipic, 'rb') newstm = CombinePic(rgbf.read(), af.read()) if newstm == 0: int3() rgbf.close() af.close() else: newstm = rgbf.read() rgbf.close() newf = open(path2 + pic + '\\' + ipic, 'wb') newf.write(newstm) newf.close() else: rgbf = open(path1 + pic, 'rb') fn, bn = pic.rsplit('.', 1) if fn + '$.' + bn in oris: af = open(path1 + fn + '$.' + bn, 'rb') newstm = CombinePic(rgbf.read(), af.read()) if newstm == 0: int3() rgbf.close() af.close() else: newstm = rgbf.read() rgbf.close() if newstm != 0: newf = open(path2 + pic, 'wb') newf.write(newstm) newf.close()
def CombineDir(path1,path2): oris=os.listdir(path1) for pic in oris: if pic.rsplit('.',1)[0].endswith('$'): continue if os.path.isdir(path1+pic): if not os.path.exists(path2+pic): os.makedirs(path2+pic) inpics=os.listdir(path1+pic) if pic+'$' not in oris: nomsk=1 else: nomsk=0 for ipic in inpics: rgbf=open(path1+pic+'\\'+ipic,'rb') if not nomsk: if not os.path.isfile(path1+pic+'$\\'+ipic): continue af=open(path1+pic+'$\\'+ipic,'rb') newstm=CombinePic(rgbf.read(),af.read()) if newstm==0: int3() rgbf.close() af.close() else: newstm=rgbf.read() rgbf.close() newf=open(path2+pic+'\\'+ipic,'wb') newf.write(newstm) newf.close() else: rgbf=open(path1+pic,'rb') fn,bn=pic.rsplit('.',1) if fn+'$.'+bn in oris: af=open(path1+fn+'$.'+bn,'rb') newstm=CombinePic(rgbf.read(),af.read()) if newstm==0: int3() rgbf.close() af.close() else: newstm=rgbf.read() rgbf.close() if newstm!=0: newf=open(path2+pic,'wb') newf.write(newstm) newf.close()
def p20(self): n = GetInt(self.psb.readu8()) self.text.append(self.tabcount * '\t' + 'Array:') self.tabcount += 1 t = self.psb.readu8() if t > 0x21: print('%x' % self.psb.tell()) int3() func = objTable[t] if func == 0: print('%x' % self.psb.tell()) int3() for i in range(n): func(self) self.tabcount -= 1
def p20(self): n=GetInt(self.psb.readu8()) self.text.append(self.tabcount*'\t'+'Array:') self.tabcount+=1 t=self.psb.readu8() if t>0x21: print('%x'%self.psb.tell()) int3() func=objTable[t] if func==0: print('%x'%self.psb.tell()) int3() for i in range(n): func(self) self.tabcount-=1
def PackWap(args): bmpfs,idxfname=args fs=open(idxfname,'rb') idxstm=bytearray(fs.read()) fs.close() if len(idxstm)!=len(bmpfs)*0x18: print('文件个数不匹配!\n请确保%s所在文件夹中有从0000开始的所有文件'%bmpfs[0]) sys.exit() wapbody=bytearray() for i in range(len(bmpfs)): print('Processing '+bmpfs[i]) fs=open(bmpfs[i],'rb') bmp=fs.read() fs.close() iw,ih,ix,iy=unpack('IIII',idxstm[i*0x18:i*0x18+16]) magic, bmp_size, off_bits=unpack('<HI4xI',bmp[0:14]) hdr_size, width, height, planes, bit_count=unpack('<IIiHH',bmp[14:30]) if bit_count!=32: print('Bit count not match!') int3() if height<0: rh=-height else: rh=height if (iw!=width) or (ih!=rh): print('Meta info not match!') idxstm[i*0x18:i*0x18+4]=pack('I',width) idxstm[i*0x18+4:i*0x18+8]=pack('I',rh) #int3() dib=bmp[off_bits:] if len(dib)<width*rh*bit_count/8: int3() if height>0: dib=reverseBmp(dib,width,rh,bit_count) dib=swapBmp(dib,width,rh,bit_count) compr=LzssPack(dib) idxstm[i*0x18+20:i*0x18+24]=pack('I',len(compr)) wapbody+=compr waphdr=pack('<4sHH',b'WAPF',len(bmpfs),0) return waphdr+idxstm+wapbody
def GetArasuji(fname): fs=open(fname,'rb') lines=fs.read().decode('U16').split('\r\n') fs.close() i=0 while i<len(lines): l=lines[i].lstrip(' ') if l.startswith('●'): ln=lines[i+1].lstrip(' ') if (ln!='是') and (ln[1]!='是'): print(fname) int3() return lines[i-1] i+=1 print(fname+' not find') return ''
def ExtTxt(stm): if stm.read(2)!=b'\xfa\xfa': int3() if stm.readu32()!=0x53514952: int3() if stm.readu32()!=1: int3() GetPart(stm) if stm.read(4)!=b'LIAT': int3()
def swapBmp(dib,w,h,bitcount): if (bitcount!=24) and (bitcount!=32): print('Can only process 24 and 32 bit pic!.') int3() bc=int(bitcount/8) newdib=bytearray(h*w*bc) k=0 if bc==3: for i in range(3): for j in range(h*w): newdib[k]=dib[j*3+i] k+=1 else: for i in range(4): for j in range(h*w): newdib[k]=dib[j*4+(4-i-1)] k+=1 return newdib
def ParsePsb(psb): psb.seek(4) version, offIdTree, offStrList, offStrRes, offMetadata=\ unpack('I4xIII12xI',psb.read(0x24)) psb.seek(offStrList) n=GetInt(psb,psb.readu8()) t=psb.readu8() strings=[] for i in range(n): p=GetInt(psb,t) pos=psb.tell() psb.seek(p+offStrRes) strings.append(psb.readstr().decode('utf-8')) psb.seek(pos) psb.seek(offMetadata) text=[] while psb.tell()<offStrList: o=psb.readu8() #print('%x'%(psb.tell()-1),':','%x'%o) t=lenTbl[o] if t==-1: print('%x'%psb.tell()) int3() elif t==-2: len1=GetInt(psb,o-(0x15-0xd)) text.append(strings[len1]) elif t==-3: len1=GetInt(psb,psb.readu8()) type1=psb.readu8() for i in range(len1): GetInt(psb,type1) elif t==-4: len1=GetInt(psb,psb.readu8()) type1=psb.readu8() for i in range(len1): GetInt(psb,type1) len2=GetInt(psb,psb.readu8()) type2=psb.readu8() for i in range(len2): GetInt(psb,type2) else: psb.seek(t,1) return '\r\n'.join(text)
def ParsePsb(psb): psb.seek(4) version, offIdTree, offStrList, offStrRes, offMetadata=\ unpack('I4xIII12xI',psb.read(0x24)) psb.seek(offStrList) n = GetInt(psb, psb.readu8()) t = psb.readu8() strings = [] for i in range(n): p = GetInt(psb, t) pos = psb.tell() psb.seek(p + offStrRes) strings.append(psb.readstr().decode('utf-8')) psb.seek(pos) psb.seek(offMetadata) text = [] while psb.tell() < offStrList: o = psb.readu8() #print('%x'%(psb.tell()-1),':','%x'%o) t = lenTbl[o] if t == -1: print('%x' % psb.tell()) int3() elif t == -2: len1 = GetInt(psb, o - (0x15 - 0xd)) text.append(strings[len1]) elif t == -3: len1 = GetInt(psb, psb.readu8()) type1 = psb.readu8() for i in range(len1): GetInt(psb, type1) elif t == -4: len1 = GetInt(psb, psb.readu8()) type1 = psb.readu8() for i in range(len1): GetInt(psb, type1) len2 = GetInt(psb, psb.readu8()) type2 = psb.readu8() for i in range(len2): GetInt(psb, type2) else: psb.seek(t, 1) return '\r\n'.join(text)
def ExtTxt(self): self.txt=[] if self.stm.read(2)!=b'\xfa\xfa': int3() if self.stm.readu32()!=0x53514952: int3() if self.stm.readu32()!=1: int3() self.GetPart() if self.stm.read(4)!=b'LIAT': int3() return self.txt
def ImpTxt(self,lines): if len(lines)!=len(self.txt): print("Lines not match!") int3() #int3() for i in range(len(lines)): if lines[i]==self.txt[i]: continue off=self.txttbl[i] self.stm.seek(off+4) slen=self.stm.readu32() nstr=lines[i].replace('\\n','\n').encode('936','replace') self.stm[off+4:off+8+slen]=struct.pack('I',len(nstr))+nstr j=i+1 dist=len(nstr)-slen while j<len(self.txttbl): self.txttbl[j]+=dist j+=1 return self.stm
def GetBracket(mes): op=mes.readu8() ctnt=[] while op!=1: if op==0xe2: ctnt.append(mes.readu8()) elif op==0xe3: ctnt.append(mes.readu16()) elif op==0xe4: val=mes.readu32() ctnt.append(val) elif op==0xe5: ctnt.append(mes.readstr()) elif (op>=0xe6) and (op<=0xe8): ctnt.append(mes.readu16()) elif (op>=0xb0) and (op<=0xd5): ctnt.append(op*-1) else: print('%x'%mes.tell()) int3() op=mes.readu8() return ctnt
def GetBracket(mes): op = mes.readu8() ctnt = [] while op != 1: if op == 0xe2: ctnt.append(mes.readu8()) elif op == 0xe3: ctnt.append(mes.readu16()) elif op == 0xe4: val = mes.readu32() ctnt.append(val) elif op == 0xe5: ctnt.append(mes.readstr()) elif (op >= 0xe6) and (op <= 0xe8): ctnt.append(mes.readu16()) elif (op >= 0xb0) and (op <= 0xd5): ctnt.append(op * -1) else: print('%x' % mes.tell()) int3() op = mes.readu8() return ctnt
def p21(self): n=GetInt(self.psb.readu8()) t=self.psb.readu8() keys=[GetInt(t) for i in range(n)] if n!=GetInt(self.psb.readu8()): print('%x'%self.psb.tell()) int3() t=self.psb.readu8() vals=[GetInt(t) for i in range(n)] self.tabcount+=1 for i in range(n): self.retAddr.append(self.psb.tell()) self.text.append(self.tabcount*'\t'+str(keys[i])+': ') self.psb.seek(self.retAddr[-1]+vals[i]) t=self.psb.readu8() func=objTable[t] func(self) if i!=n-1: self.psb.seek(self.retAddr.pop()) else: self.retAddr.pop() self.tabcount-=1
def p21(self): n = GetInt(self.psb.readu8()) t = self.psb.readu8() keys = [GetInt(t) for i in range(n)] if n != GetInt(self.psb.readu8()): print('%x' % self.psb.tell()) int3() t = self.psb.readu8() vals = [GetInt(t) for i in range(n)] self.tabcount += 1 for i in range(n): self.retAddr.append(self.psb.tell()) self.text.append(self.tabcount * '\t' + str(keys[i]) + ': ') self.psb.seek(self.retAddr[-1] + vals[i]) t = self.psb.readu8() func = objTable[t] func(self) if i != n - 1: self.psb.seek(self.retAddr.pop()) else: self.retAddr.pop() self.tabcount -= 1
def extbgi(stm): res_off_min=stm.rfind(b'\x00\x00\x00') newtxt=[] while stm.tell()<res_off_min+5: code=stm.read(1) if code==b'\x14' and stm[stm.tell()]==0: stm.seek(1,1) name=stm.readstr() if stm[stm.tell()]==0 or stm[stm.tell()]<0x80: continue stm.seek(stm.find((b'\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00'),stm.tell())+10) off=stm.readu32() if off<=res_off_min: int3() cur=stm.tell() stm.seek(off) newtxt.append(stm.readstr()) newtxt.append(name) stm.seek(cur) elif code==b'\x10' and stm[stm.tell():stm.tell()+9]==(b'\x00'*5+b'\x01\x00\x00\x00'): stm.seek(9,1) off=stm.readu32() if off<=res_off_min: stm.seek(-4,1) continue cur=stm.tell() stm.seek(off) if stm[stm.tell()]!=0: newtxt.append(stm.readstr()) stm.seek(cur) elif code==b'\xb0' and stm[stm.tell()]==0: stm.seek(1,1) count=stm.readu32() if count>5 or count==0: stm.seek(-4,1) continue for i in range(count): newtxt.append(stm.readstr()) return b'\r\n'.join(newtxt)
def Parse(self): while self.vmcode.tell() < len(self.vmcode): self.text.append("%08X\t" % self.vmcode.tell()) self.code = self.vmcode.readu16() if self.code >= 0x800 and self.code <= 0x850: func = self.code800[self.code - 0x800] if func == 0: int3() func(self) elif self.code <= 0x1A9 and self.code >= 0x100: self.p10X() elif self.code >= 0x1B8 and self.code <= 0x200: self.p1BX() elif self.code >= 0x218 and self.code <= 0x260: self.p21X() elif self.code >= 0x270 and self.code <= 0x2C0: self.p27X() elif self.code >= 0x2D0 and self.code <= 0x320: self.p2DX() elif self.code <= 0x850: self.pLen8() else: int3() return "\r\n".join(self.text)
def GetOp(mes): op = mes.readu8() while op == 0x12: op = mes.readu8() if op == 0: print('%x' % mes.tell()) int3() if op == 2: return (2, 0) if (op == 3) or (op == 4): n = mes.readu8() if n != 0xe4: print('%x' % mes.tell()) int3() return (op, mes.readu32()) if op > 0x7b: print('%x' % mes.tell()) int3() return -1 if (op == 0x13) or (op == 0x14): return (op, GetBracket(mes)) if (op == 0x11): return (op, mes.readstr()) if op == 0x10: print('%x' % mes.tell()) int3() if (op < 4) or ((op > 5) and (op < 0x15)) or (op > 0x7b): return (op, 0) if op <= 5: return (op, 0) nextop = mes.readu8() if nextop <= 3: mes.seek(-1, 1) return (op, 0) paras = [] while nextop > 3: if (nextop >= 0x10) and (nextop <= 0x7b): break para = GetPara(mes, nextop) if para == -1: break paras.append(para) nextop = mes.readu8() mes.seek(-1, 1) return (op, paras)
def GetOp(mes): op=mes.readu8() while op==0x12: op=mes.readu8() if op==0: print('%x'%mes.tell()) int3() if op==2: return (2,0) if (op==3) or (op==4): n=mes.readu8() if n!=0xe4: print('%x'%mes.tell()) int3() return (op,mes.readu32()) if op>0x7b: print('%x'%mes.tell()) int3() return -1 if (op==0x13) or (op==0x14): return (op,GetBracket(mes)) if (op==0x11): return (op,mes.readstr()) if op==0x10: print('%x'%mes.tell()) int3() if (op<4) or ((op>5) and (op<0x15)) or (op>0x7b): return (op,0) if op<=5: return (op,0) nextop=mes.readu8() if nextop<=3: mes.seek(-1,1) return (op,0) paras=[] while nextop>3: if (nextop>=0x10) and (nextop<=0x7b): break para=GetPara(mes,nextop) if para==-1: break; paras.append(para) nextop=mes.readu8() mes.seek(-1,1) return (op,paras)
def SScan(stm): while stm.tell()<len(stm): opcode,oplen,code1,code2=unpack('BBBB',stm.read(4)) if opcode>0xa6: print('%x'%stm.tell()) int3() if spec_table[opcode]==0: if opcode==0 or opcode==2 or opcode==0xf or opcode==0x10\ or opcode==0x12 or opcode==0x3c or opcode==0x58: stm.seek(oplen-4+code2,1) else: stm.seek(oplen-4,1) elif spec_table[opcode]==3: int3() stm.seek(oplen-4+code1,1) elif spec_table[opcode]==1: strlen,=unpack('3xB',stm.read(4)) stm.seek(oplen-8+strlen,1) elif spec_table[opcode]==2: strlen,=unpack('4xB3x',stm.read(8)) stm.seek(oplen-12+strlen,1) else: int3()
def CheckMagic(stm): if stm.readu32()!=0x50415254: int3()
def packNpa(thedir, fname, is_compr, is_crypt): if not thedir.endswith('\\'): thedir += '\\' namepos = len(thedir) idxlen = 0 dircount = 0 filecount = 0 dirss = [] for root, dirs, files in os.walk(thedir): dirlen = len(root[namepos:].encode('932')) if dirlen > 0: idxlen += 0x15 + dirlen dirss.append(root[namepos:].encode('932')) dircount += 1 else: dirlen = -1 dirss.append('') for f in files: idxlen += 0x15 + dirlen + 1 + len(f.encode('932')) filecount += 1 fs = open(fname, 'wb') idx = [] curpos = 0 curdir = 0 fs.seek(0x29 + idxlen) for root, dirs, files in os.walk(thedir): dirlen = len(root[namepos:].encode('932')) if dirlen > 0: rtdir = root[namepos:] + '\\' entry = [0 for i in range(12)] entry[0] = bytearray(root[namepos:].encode('932')) entry[1] = 1 if '\\' not in rtdir[0:-1]: entry[2] = 0 else: entry[2] = dirss.index(rtdir[0:-1].rsplit('\\', 1)[0]) entry[3] = curpos entry[10] = hash0 entry[11] = hash1 idx.append(entry) curdir += 1 else: rtdir = u"" for f in files: entry = [0 for i in range(12)] entry[0] = bytearray((rtdir + f).encode('932')) entry[1] = 2 entry[2] = curdir entry[3] = curpos infs = open(root + os.sep + f, 'rb') entry[5] = os.path.getsize(root + os.sep + f) entry[6] = is_crypt entry[7] = is_compr entry[10] = hash0 entry[11] = hash1 if is_compr: stm = bytearray(zlib.compress(infs.read())) else: stm = bytearray(infs.read()) infs.close() entry[4] = len(stm) if is_crypt: Encrypt2(entry, stm) fs.write(stm) curpos += len(stm) idx.append(entry) for i in range(len(idx)): EncryptEntry(idx[i], i) idxbf = bytearray() for entry in idx: idxbf += pack('I', len(entry[0])) idxbf += entry[0] idxbf += pack('<BIIII', entry[1], entry[2], entry[3], entry[4], entry[5]) if len(idxbf) != idxlen: int3() hdr=pack('<3sIIIBBIIIIII','NPA',1,hash0,hash1,is_compr,is_crypt,\ filecount+dircount,dircount,filecount,0,0,idxlen) fs.seek(0) fs.write(hdr) fs.write(idxbf) fs.close()
dec_len = 64 key1 = ci[5] d = 0x31746285 for i in range(dec_len): d = ((d << 28) & 0xffffffff) | (d >> 4) shift = d & 0x1f tempkey = [ key1 & 0xff, (key1 & 0xff00) >> 8, (key1 & 0xff0000) >> 16, (key1 & 0xff000000) >> 24 ] for j in range(4): dest[i * 4 + j] ^= tempkey[j] key1 = (key1 >> (32 - shift)) | ((key1 << shift) & 0xffffffff) return ci[6] + dest fname = 'sys.lpk' fs = open(fname, 'rb') int3() idx, key0, key1 = DecHdr(fs, fname.rsplit('\\', 1)[-1], lpkkey.key) dirs = ExtDir(idx, key0, key1) dirname = fname.rsplit('\\', 1)[-1].rsplit('.', 1)[0] if dirname not in os.listdir('.'): os.mkdir(dirname) os.chdir(dirname) for fe in dirs: fc = ExtSingleFile(fe, fs) newf = open(fe[0], 'wb') newf.write(fc) newf.close()
def DecSingle(stm): for i in range(len(stm)): stm[i]^=dec_key[i&7] int3() return zlib.decompress(stm[4:])
def packNpa(thedir,fname,is_compr,is_crypt): if not thedir.endswith('\\'): thedir+='\\' namepos=len(thedir) idxlen=0 dircount=0 filecount=0 dirss=[] for root,dirs,files in os.walk(thedir): dirlen=len(root[namepos:].encode('932')) if dirlen>0: idxlen+=0x15+dirlen dirss.append(root[namepos:].encode('932')) dircount+=1 else: dirlen=-1 dirss.append('') for f in files: idxlen+=0x15+dirlen+1+len(f.encode('932')) filecount+=1 fs=open(fname,'wb') idx=[] curpos=0 curdir=0 fs.seek(0x29+idxlen) for root,dirs,files in os.walk(thedir): dirlen=len(root[namepos:].encode('932')) if dirlen>0: rtdir=root[namepos:]+'\\' entry=[0 for i in range(12)] entry[0]=bytearray(root[namepos:].encode('932')) entry[1]=1 if '\\' not in rtdir[0:-1]: entry[2]=0 else: entry[2]=dirss.index(rtdir[0:-1].rsplit('\\',1)[0]) entry[3]=curpos entry[10]=hash0 entry[11]=hash1 idx.append(entry) curdir+=1 else: rtdir=u"" for f in files: entry=[0 for i in range(12)] entry[0]=bytearray((rtdir+f).encode('932')) entry[1]=2 entry[2]=curdir entry[3]=curpos infs=open(root+os.sep+f,'rb') entry[5]=os.path.getsize(root+os.sep+f) entry[6]=is_crypt entry[7]=is_compr entry[10]=hash0 entry[11]=hash1 if is_compr: stm=bytearray(zlib.compress(infs.read())) else: stm=bytearray(infs.read()) infs.close() entry[4]=len(stm) if is_crypt: Encrypt2(entry,stm) fs.write(stm) curpos+=len(stm) idx.append(entry) for i in range(len(idx)): EncryptEntry(idx[i],i) idxbf=bytearray() for entry in idx: idxbf+=pack('I',len(entry[0])) idxbf+=entry[0] idxbf+=pack('<BIIII',entry[1],entry[2],entry[3],entry[4],entry[5]) if len(idxbf)!=idxlen: int3() hdr=pack('<3sIIIBBIIIIII','NPA',1,hash0,hash1,is_compr,is_crypt,\ filecount+dircount,dircount,filecount,0,0,idxlen) fs.seek(0) fs.write(hdr) fs.write(idxbf) fs.close()
def DecSingle(stm): for i in range(len(stm)): stm[i] ^= dec_key[i & 7] int3() return zlib.decompress(stm[4:])
for f in os.listdir(path1): fs=open(path1+f,'rb') lines=fs.read().decode('utf-16').replace('<BR>','\\n').split('\r\n') fs.close() ptext=[] tags=[] print f for li in lines: text='' cur=0 while cur<len(li): if li[cur]=='<': p=cur while li[p]=='<': p=li.find('>',p)+1 if p==-1: int3() if p==len(li): break tags.append(li[cur:p]) text+='@' cur=p else: p=li.find('<',cur) if p==-1: p=len(li) text+=li[cur:p] cur=p ptext.append(text) textf=open(path2+f,'wb') textf.write('\r\n'.join(ptext).encode('utf-16')) textf.close()
def PackWip(args): bmpfs,idxfname=args fs=open(idxfname,'rb') idxstm=bytearray(fs.read()) fs.close() if len(idxstm)!=len(bmpfs)*0x18: print('文件个数不匹配!\n请确保%s所在文件夹中有从0000开始的所有文件'%bmpfs[0]) sys.exit() g_bitcount=8 wipbody=bytearray() for i in range(len(bmpfs)): print('Processing '+bmpfs[i]) fs=open(bmpfs[i],'rb') bmp=fs.read() fs.close() iw,ih,ix,iy=unpack('IIII',idxstm[i*0x18:i*0x18+16]) magic, bmp_size, off_bits=unpack('<HI4xI',bmp[0:14]) hdr_size, width, height, planes, bit_count=unpack('<IIiHH',bmp[14:30]) if (i!=0) and (g_bitcount!=bit_count): print('Bit count not match!') int3() if (bit_count!=8) and (bit_count!=24): print('Bit count must be 8 or 24') int3() g_bitcount=bit_count if height<0: rh=-height else: rh=height if (iw!=width) or (ih!=rh): print('Meta info not match!') erri=bmpfs[i]+' orignal width:%d height:%d\n\tcurrent width:%d height:%d'%(iw,ih,width,rh) metaErrors.append(erri) idxstm[i*0x18:i*0x18+4]=pack('I',width) idxstm[i*0x18+4:i*0x18+8]=pack('I',rh) #int3() if bit_count==8: pallete=bmp[off_bits-0x400:off_bits] else: pallete=b'' dib=bmp[off_bits:] if len(dib)<width*rh*bit_count/8: int3() if height>0: dib=reverseBmp(dib,width,rh,bit_count) if bit_count!=8: dib=swapBmp(dib,width,rh,bit_count) compr=LzssPack(dib) idxstm[i*0x18+20:i*0x18+24]=pack('I',len(compr)) wipbody+=pallete+compr wiphdr=pack('<4sHH',b'WIPF',len(bmpfs),g_bitcount) return wiphdr+idxstm+wipbody
for f in os.listdir(path1): fs = open(path1 + f, 'rb') lines = fs.read().decode('utf-16').replace('<BR>', '\\n').split('\r\n') fs.close() ptext = [] tags = [] print f for li in lines: text = '' cur = 0 while cur < len(li): if li[cur] == '<': p = cur while li[p] == '<': p = li.find('>', p) + 1 if p == -1: int3() if p == len(li): break tags.append(li[cur:p]) text += '@' cur = p else: p = li.find('<', cur) if p == -1: p = len(li) text += li[cur:p] cur = p ptext.append(text) textf = open(path2 + f, 'wb') textf.write('\r\n'.join(ptext).encode('utf-16')) textf.close()
newtxt.append(text[cur:p]) if p==-1: break newtxt.append(tags[i]) i+=1 cur=p+1 return ''.join(newtxt) for f in os.listdir(path1): fs=open(path1+f,'rb') lines=fs.read().decode('utf-16').replace('<BR>','\\n').split('\r\n') fs.close() textf=open(path2+f,'rb') ptext=textf.read().decode('utf-16') textf.close() tagf=open(path3+f,'rb') tags=tagf.read().decode('utf-16').split('\r\n') tagf.close() print f if len(tags)!=ptext.count('@') and (len(tags)>1 or len(tags[0])!=0): print '标记数目不匹配!' int3() newtxt=repAt(ptext,tags) newf=open(path4+f,'wb') newf.write(newtxt.replace('\\n','<BR>').encode('utf-16')) newf.close() print '\nSuccess!' input()