![]() Yes, you've identified the fundamental problem with the optimistic approach. There's a standard technique for this that is as old as variable-length ISA's. Do you know if fasm and others actually do this? (Looks like nasm has a command-line switch to turn off multi-pass branch offset optimization.) One of the posts talks about NUMBER_OF_PASSES this suggests, but I don't think the post explicitly states, that the defense mechanism is "arbitrarily limiting the number of passes". but I'm curious if assemblers have nonetheless seriously addressed the problem. I'm sure this doesn't actually happen in practice, unless you're compiling malicious code off the internet (in which case there are likely worse vulnerabilities inside the compiler). chains go from 0 to 62, and the "more than 128 bytes of unrelated stuff" becomes "0 bytes of unrelated stuff" then, in the pessimistic approach, once the Zs have settled down, the subsequent passes will discover, one at a time, that Y62 only has a 126-byte offset and can be encoded with 2 bytes, then that Y61 can be similarly encoded, and so on. This isn't a flaw unique to the optimistic approach, by the way-I could construct a similar version where all the L, M, etc. I think it's still possible to construct an example where pessimizing Y10 kicks Y20 over the edge, which kicks Y9 over the edge, which triggers pessimizing Y21, etc.) (If the passes go from right to left, or even alternate the direction or randomize. If the total number of jmps here is n, then it will take close to n passes to fix up all the jmps. Pass 4 will discover the sole fact that Y23 needs to be 5 bytes, and so on. Pass 3 will discover that Y24 needs to be 5 bytes too, and discover nothing else. Pass 2, assuming it goes left to right, will see that everything up to Y24 still has offset ≤ 127 (even "Y24: jmp Z24" could be 127 bytes or 130 depending on how Y25's jump is encoded), but will find that "Y25: jmp Z25" has an offset of 130 and must be 5 bytes. The optimistic approach will discover in the first pass that all the Z jmps have to be 5 bytes. L0 to M0 is 130 bytes, which is over the limit of 127 you can get from an 8-bit signed offset. If all the jmps are encoded with 5 bytes, then the offset from e.g. (Supposedly x86 has a 16-bit offset version, but that uses the same opcode as the 32-bit offset, and seems unsupported in 64-bit mode.) Consider the following: Glancing at the posts, I have a question: do they defend against the pathological cases that require O(n) passes, and therefore at least naively have O(n^2) or worse behavior? Let's say that a jump can be encoded with either an 8-bit signed offset in 2 bytes, or a 32-bit signed offset in 5 bytes. And on top of that, you see C as convenience for having to do assembler. You start thinking of assembler and macros as merely convenience of having to write out hex (or binary) of the instructions you want. You almost feel like Neo in the Matrix, in more nerdy less awesome sort of way. One surprising aspect of writing an assembler is that you learn to decode instructions by simply looking at a hex dump of the binary output. Other things to make sure you understand: big/little endian, LSB/MSB, how two's-complement works, etc. Labels simply become keys in a dictionary that record the byte offset into the assembled binary data. You allocate a fixed amount of space for the jump instruction and come back later to "patch" that jump instruction with the correct byte offset. What this means to you is that you'll need to design a multi-pass assembler. Instructions can range from one byte to 15 bytes. ![]() Because x86 instructions are variable length, you can't simply count up the lines to the label and multiply by some fixed amount. Any reasonable assembler will provide symbolic labels for jumps and other operations. Understanding how this works and fits together will save you a lot of headaches.Ģ) Forward jumps are a pain. There are two gotchas that most people starting out probably won't realize until it's too late.ġ) Encoding instructions on x86 can be more challenging than they first appear. I've written a (mostly) fully-featured x86 assembler.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |