Miracle #03
16 июля 1999 |
|
kodit Who's there? - Packer'y and Depacker'y: the truth about the packer or the ranting of Sir Kot'a.
(C) Kot / North Star group 07.1998 -------------------------------- Compressors decompressors and they are not alone ... All pryuvet from a group of North Star. In this article I will address several problems of product quality "plants softovareniya" nashego immense CIS. Probably malomalski self-respecting coder (a hacker) is almost always enjoys the compressor data, whether it be a screen or code. Currently, the number programs of this type has been steadily increasing and have to choose. However, service performance, and sometimes and software features often leave much to be desired. Let's start with the program. It is known that professionally made screen decompressors relotsiruemy, I mean start carried out with the load address. Classical protsedurka "self-re-addressing" looks like this: DI;!!! CALL ret_adr; # 0052, # 1792, # 33C5 etc ; E1> DEC SP ; E2> DEC SP POP reg_p; HL, DE, BC, etc. ....... Some wise guy (we will not show finger: see ZF # 7Persprektivy POS.O.T.A.p.p. Screen Compressor) advised (and, as I recall, called lamerizmom) command to remove the first DI the entire procedure. You see, gives displeasure to hear inhibition Mouzon during a call to the decompressor ... So let's clean up this stinking x DI or morfirovat it to NOP and the program will look "elite". That is, he wants to to say that dear Andrei Sendetsky for general Ponte its ASC placed first DI because he - lamer? But no, my friend. What do we see if interrupt enable? You just Think what will remove garbage from the stack POP reg_p, if the CPU starts processing the interrupt at the points e1 and e2! If someone did not understand why it happens, let instead of e1 or e2 substitute any PUSH and the same POP (emulation transmission interruption). Here I am here "Zapachil" picture in a new LAZY_PACK. Then uploaded to the STS: the beginning of the decompressor the above "classic" ... only without the DI ... A pity. You think for - But some clean DI and decompressor type MS_PACK'a where data removed stack ... I still imagine Alternatively, when in operation with a stack SP is always a result of SP +2, but in a same decompressor MS_PACK'a available: ......... DEC SP POP AF ......... Potrassiruyte STS'om packed MS_PACK'om unit with its original decompressor and count how many times program addresses the above pieces of code. And then to calculate their own theories: will interrupt or not come to this moment and have time for a decruncher 1 / 50 seconds ... Good luck ... A striking example is TRANCE MD (SBG), where, for example, along with the characters comes out something "more uzhasnoe" ... We now turn to the so-called technical service. That's all write: we supposedly Progressive People, etc., but often the whole real indication in the program - decimal (this applies to sys-prog any purpose). Me (I'm sure not only me), this fact "mad", roughly speaking, angry. Interestingly, whether many of these "People", which for a couple of seconds to say that # B700 is 46848? I I think there are not many and I'm not one of them. Do not make the input (and display) of numerical values and in HEX'e and DEC'e. About themselves decruncher'ah special conversation. Would long ago have time to forgive the banality, "to adopt a standard" request type "And if you want to hem decruncher?" (Decompressor ON / OFF). After all, for example, how convenient zapachit all files (part of the MD, levels of games or overlays systems) in the compressor and ship them without dcrnchr'a and When unpacking, use one decompressor only. This allows for PCD, MegaLZ and DSQ, although it As for compressors, all kinds of data, including on-screen. Desirable Included give two (or more) decompressor - the choice of responsible, for example, the following conditions: using the stack when not interrupt :-) Or without the use of stack and IY in any status interrupts, etc. Options can be any number, but if per se is only one, then it should work with interrupt enable (this my personal opinion). Some will say: Here a DSQ dekompresor also works with any status interrupt, so it's probably the brake. The answer is: what As DSQ, so there is data in hryanyatsya continuous form, and these same data have raznobitnuyu value (see Figure), and decompressor itself has a fairly compact size. bit 76543210 | 76543210 | 76543210 | ---------------------------- l) 000 | 1101 | 0101010 | 01 | 01110110 | f) 00011010 | 10101001 | 01110110 | l) - logical data obtained at compression (in a form accepted decompressor) continuous, ie initial bits of the log. data unit does not sovapadaet with an initial bit of nat. units. data that gives the effect of saving bits in accordance file size (in direct proportion); f) - a physical form, ie, so data is located in the computer memory; Think logically, we can conclude that the transformation of data from the form l) in the form of f) must be applied shifts (RR, RL and etc.). Here's to it and leaves the lion's share time at the decompressor DSQ, although there are sense to optimize it. Well, that if we are talking about DSQ, then discuss it in detail. As you know, DSQ possible to stop the decompressor. But this is half the battle. In prog DSQ_INFO, as often happens, instead of descriptions - Hello, and kominsuny any such nonsense. So, if you decided to use castrated (without dkmprsr'a) dataskviznuty blochok, then if you please know the following things: it turns out that this block has a header (len: 6 byte, but the idea should be 7 - see below), which indicated: N0 (byte) - the number of "cuts" window of bits (much the way that fits definition); N1 (word) - the address entered in the query DECRUNCH CODE TO: NNNN; N2 (word) - Address, N1-1 + the real length file, in other words - the address of the last byte of the file (it is the latter, but not following it); N3 (byte, and must be a word) - strongly Do not laugh, but it is the low byte address introduced at the request AUTOSTART: NNNN, just a small glitch DSQ; Total: byte + word + word + byte = 6 byte. In fact, besides more bytes N0 a damn do not have, the more significant byte start :-). You can, in principle, to leave on-site N1 full length of the source file. But this - advice for those who can be transformed DSQ in a new way (With a cool service, etc.). Reasonable question: what to do with N0? ......... LD B, NN; nuf LD H, # 2002 ADD HL, DE CALL NNNN ADD HL, BC POP BC LDDR LD HL, XXXX; nif SBC HL, DE JR C, NNNN POP HL EXX RET .......... The argument of ref. B in a row and have nuf same N0, and for full understanding statements about the "window bits" potrassiruyte decompressor debugger'om. N0 option depends on what was selected window size When packing file. And how do extract the block is not native decompressor? First, DSQ in general is not an ordinary compressor. Let me explain why. If you know the order of data transmission "native" decompressor packer LPC, PCD, CC, MS_PACK, then able to observe the following picture: 1) block LDIR (LDDR) on body file (To perform end_block = end_file) 2) source (HL) = start_block 3) destination (DE) = start_file LP 4) translate (HL) bits to (DE) bytes 5) inc HL, inc DE 6) go to LP if DE <(end_file +1) In all DSQ "up side down": 1) block LDIR (LDDR) on body file (To perform start_block = start_file) 2) source (HL) = end_block 3) destination (DE) = end_file LP 4) translate (HL) bits to (DE) bytes 5) dec HL, dec DE 6) go to LP if DE <(start_file-1) Profanity: file - the original file; block - the result of compression; source - from where we take; destin - where to put; start_file - start address dkmprsiruemyh data; end_file - the address of the last byte dkmprsiruemyh data; start_block - beginning of the data block'a; end_block - the address of the last byte block'a; inc, dec - increase, decrease in NNNN bytes (contrary to legend - not only per unit); body file - a chunk of memory, redundant under the file; Generally, these schemes are in the ideal. In fact for DSQ There are some impressive amendment. If you do enjoy the DSQ, you probably remember something (-2). This occurs because destin'atsiya is faster sour'sirovanie than as a result, when remains unpacked 1-3 bytes is equal to destination source, and the next cycle generally ahead of him. Here and there situation when, for example, the marker end is taken "something" whose probability to be a marker of the end of 1 / 256 ... Therefore LDIR'it or LDDR'it must be so to start_blok = start_file-2 (-2, -3 and more but not less than -2), and if the block DSQ with the headline, then start_block = start_file-2-6 (-8, -9, and more, not less than -8). All this, of course, the glory of DSQ does not add to, and in fact could be as a PCD or MS_PACK'e using the buffer - there everything works according to the above scheme as a "native" or "not family" dkmprsrami. Note: nif in a chunk disassembler dehryunchera posed not by accident - there must necessarily be start_file-one! Finish with DSQ and return to # 1B00, ie to skrinovym packer. Put forward more one suggestion: why, even in compressors, the screen does not provide the possibility of a change of address extraction? About What are you, old man? You will probably faced a situation when you have decompress the image on the SCR1 (in the seventh page), ie under the address # C0 or even unpacked at # 40 and not # C0, and go somewhere "in general nor there" (eg, when implementing any gasilok / Lighters and other "manifestations"). My suggestion is to be able to choose the least senior part destin'atsii, a junior would be zero "by default" For example, # 70, # 67, # BF, # 9A, # DE, etc. A then after unpacking in any way it (the picture) show (you can even LDIR'om :-)). Now back to "relotsiruemomu Start programs. I will give you a set of small procedures that provide "self-location": 1) DI; required! (See above) CALL ROM_RET; # 52, # 7C, # 33C5, etc. DEC SP DEC SP POP reg_p; HL, DE, BC, IX, etc. ........ ; Length: 7-8 bytes 2) LD HL, # E9E1; POP HL (# E1) LD (# 4000), HL; JP (HL) (# E9) CALL # 4000; .......... And the result in HL ; Length: 9 bytes 3) LD HL, # 4000; <- start_1 PUSH HL; <- start_2 LD (HL), # E1 INC HL LD (HL), # E9 DEC HL CALL ROM_JHL; JP (HL): # 162C, # 6F ........ And the result in HL POP reg_p; length: 14 bytes The first option works only if Interrupt prohibited, but the address can be placed in any of register pairs. Used ROM-48. The second option is for 1-2 bayta, but works with any status prervyvany and does not use ROM. The third option yavyaetsya universal but again uses ROM. There is two points of entry and start_1 start_2. Through start_1 by binding unpack the data to a fixed memory address, using the same start_2 you themselves are free to choose the address, but it is important to younger, too, was equal to zero (Depending how the counting is "screen" addresses dkmprsrom - a condition: (not) allowed to use a non-zero low part). In general, options may be much anywhere, as long as it was convenient, cool and no bugs :-(. A few days ago looked inlaytskie demos and one of them (Art Vision by etc group) learned that, say, uses the deme decruncher ((c) LAZY) MS_PACK'a that does not use the stack for "pumping" the data etc. Since the MSP is not provided Off the decompressor, the "new" dkmprsr works with building blocks MSP, which already has a decompressor. ; MS_PACK blocks decruncher ; Written by LAZY / etc group ; Entry: IX - adr of block ; (Wiz standard decruncher) INC HX LD L, (IX-# 17) LD H, (IX-# 16) LD DE, MSPBUF +4 LD BC, # 0005 LDDR LD L, (IX-# 15) LD H, (IX-# 14) LD E, (IX-# 13) LD D, (IX-# 12) LD C, (IX-# 11) LD B, (IX-# 10) LDDR INC DE INC DE INC DE EX DE, HL LD E, (HL) INC HL LD D, (HL) INC HL EX DE, HL LD BC, # 1010 EXX LD E, (IX-# 0F) LD D, (IX-# 0E) MSP_LP CALL MSPCOD JR C, LL631D CALL MSPBYT LD (DE), A INC DE JR MSP_LP LL631D LD HL, # 0302 LL6320 LD B, # 02 CALL BCOD_A CP H JR C, LL632F ADD A, L LD L, A CP # 11 JR NZ, LL6320 XOR A LL632F ADD A, L CP # 05 JR NC, LL6364 CP # 02 JR NZ, LL6367 LD C, A LL6339 XOR A LL633A LD H, A CALL MSPBYT LD L, A LD A, E SCF SBC A, L LD L, A LD A, D SBC A, H LD H, A LDIR JR MSP_LP LL634A CALL MSPBYT INC A JR Z, MSPEND INC A JR NZ, LL635D CALL MSPBYT LD C, A CALL MSPBYT LD B, A JR LL6368 LL635D ADD A, # 0F JR NC, LL6367 INC B JR LL6367 LL6364 JR Z, LL634A DEC A LL6367 LD C, A LL6368 CALL MSPCOD JR C, LL6339 LD L, B LD B, H CALL BCOD_A LD B, L CP # 02 JR NC, LL637A INC A JR LL633A LL637A CALL LL63B1 CP # 08 JR NC, LL6384 DEC A JR LL633A LL6384 CALL LL63B1 CP # 17 JR NC, LL638F SUB # 09 JR LL633A LL638F CALL LL63B1 AND # 1F CP # 1F JR C, LL633A CALL MSPBYT JR LL633A MSPEND LD HL, MSPBUF LD BC, # 0005 LDIR LD HL, # 2758 EXX RET BCOD_A XOR A CALL LL63B1 DJNZ $ -3 RET LL63B1 CALL MSPCOD RLA RET MSPCOD EXX ADD HL, HL DJNZ NONEXT LD B, C EX DE, HL LD E, (HL) INC HL LD D, (HL) INC HL EX DE, HL NONEXT EXX RET MSPBYT EXX LD A, (DE) INC DE EXX RET MSPBUF DEFB 0,0,0,0,0 Well, probably, and all I wanted to tell you. If anyone has any comments, let MIRACLE wrote to the editor or me (Kot'u). Bye'te! Kot / NSG 07.1998 Kirovsk-apatite-Olenegorsk ---------------------------------------
Other articles:
Similar articles:
В этот день... 21 November