It so happened that in my free time, I began to write programs. The right (maybe) programs, programs that I liked (and liked) to write - programs that I like to use. So far there are two of them. In principle, these are quite large programs (more than 2 MB of source code each). When creating them, it was possible to stumble upon “incomprehensible oddities” rather “incorrect”, at first glance, the behavior of the compiler / program and the operating system. After debriefing, once again made sure that I am SZZB (to myself angry
buratinko ). In any case - a couple of examples, how I buggy and how not to do it (everything under Win32 - Intel86).
Example one')
Wasp (the name is what)). A program that intercepts calls to functions of third-party processes to dlkam, and allows you to change the input / output parameters of these intercepted functions. The spoof functions themselves are executed on the stack machine - there is no problem with them. But in order to transfer control to them, you need to initialize the stack machine. To do this, you need a bit of memory where the jump will jump either from the beginning of the intercepted function (of course, if it is successfully disassembled), or from the import tables of other PE files (ekzeshki and dll) loaded into the process memory. Memory can be taken in three places:
• Find a place in the sections of the downloaded file - in general, it is impossible.
• In the stack - perhaps, but troublesome.
• Heap - and chose it.
The wasp loaded Dll into the memory of a third-party process, it allocated memory for the bytecode and filled it, allocated memory for pure x86 code that prepares the stack machine and calls it. And everything worked. Everywhere. Almost everywhere). It was on whist that two instances of the running Far manager with an interval of less than 3 seconds, with intercepted file access functions, died. Processes said that they performed an illegal operation and will be closed. Having sat for an hour for the debugger, I realized the simplest truth - the memory allocated to the process from the heap may not be executable. For some reason, this had never occurred before (heh why). Sometimes, in certain situations, certain versions of Windows, when allocating memory with the new operator, can do what they have the right to give memory with a non-executable attribute (read-only write). Next, using the WinApi function, you must assign this attribute (if I’m not mistaken to the page or pages) to the execution attribute, if you want to execute the machine code directly in this memory.
Example twoVisual C ++ vs
OSProtectorProtectors, they are trying to protect the program from evil hackers). And they also need memory, memory in the executable file. They take the memory either by increasing the size of the last section, or by adding new ones, or replacing the old ones altogether (as a rule, with the packaging of the sections). In any case, the protectors change the section table (located at the beginning of the file). Currently, Visual C ++ in the start code of compiled applications checks the integrity of the partition table. If it has changed, then the
Runtime error R6002 floating point is not loaded when the application starts. When trying to protect the same Far manager (v 1.7) protector, everything was fine. When trying to protect the Far manager (v 2.0) with a protector, everything was not good - obviously it was compiled with a newer version of the compiler. Google found:
www.manhunter.ru/underground/65_runtime_error_r6002_floating_point_not_loaded.htmlAnyway, OSProtector, before transferring control to the start code, now restores the original attributes of sections of the protected file.