- Change one function pointer in Vtable - 18 Updates
- ::errno - 2 Updates
- [Jesus Loves You] Tag for filtering - 3 Updates
- Scott Newman - 2 Updates
Scott Newman <scott69@gmail.com>: Jun 08 09:12PM +0200 >> That'S very unlikely with such a basic feature. > UB is a bug, not a feature. UB is what the standard says, not the implementation. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 08 03:12PM -0400 On 6/8/20 3:04 PM, Scott Newman wrote: >> How many different implementation of C++ have you actually verified that >> assumption for? Please list them. > It's just the most obvious way to do it like Cfront. So you're just assuming it, without any verification. Good luck with that. It's the norm, not the exception, that clever people often find reasons (sometimes good, sometimes not so good) for doing things in in-obvious ways. > And there is no reason to do it differently. There's no reason that you know of. Unless you're intimately familiar with the detailed design of many different compilers, targeting a wide variety of different kinds of platforms, I wouldn't recommend treating the fact that you don't know of a reason as evidence that there is no such reason. |
Scott Newman <scott69@gmail.com>: Jun 08 09:14PM +0200 > So you're just assuming it, without any verification. There's no reason to do it differently than Cfront. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 08 12:47PM -0700 >> something you didn't think it could do, no, you can't do that. > The whole thing is predictable since no compiler behaves differently > than cfront. Prove it. Note that proving your claim would require examining every existing C++ compiler with every set of options -- and even that would not tell us anything about a new version of some compiler released tomorrow. And please don't snip attribution lines from your followups. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 08 12:49PM -0700 >> So you're just assuming it, without any verification. > There's no reason to do it differently than Cfront. Thank you for confirming that you're just assuming it without any verification. (And please stop snipping attribution lines.) -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
David Brown <david.brown@hesbynett.no>: Jun 08 09:50PM +0200 On 08/06/2020 21:04, Scott Newman wrote: >> assumption for? Please list them. > It's just the most obvious way to do it like Cfront. > And there is no reason to do it differently. Of course there are good reasons to do it differently - optimisation. That is why any good compiler will de-virtualise calls when it can, skipping the use of a vtable. If the compiler knows the /real/ type of an object, then it doesn't bother looking up the vtable for a pointer to a virtual method - it will go straight to that virtual method because it knows that no one could possibly have changed the vtable data and this optimisation is perfectly valid. And if it can see the definition of the method, it can be inlined in the calling code - even though the method is virtual. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 08 04:09PM -0400 On 6/8/20 3:09 PM, Scott Newman wrote: >> something you didn't think it could do, no, you can't do that. > The whole thing is predictable since no compiler behaves differently > than cfront. Even if it were true that all implementations use exactly the same method (which would strike me as quite unlikely even if I didn't know that, for instance, some implementations put the pointer at the beginning of the object, and some at the end of the object), that still wouldn't be enough to make such code safe. Because the behavior is undefined, implementations are free to perform optimizations based upon the assumption that you won't do anything that stupid. In particular, one of the most basic and common optimizations is that if the implementation knows precisely which class's version of a virtual member function should be called, it will call that function directly, rather than calling it indirectly through the vtable. This not only would result in your vtable modification sometimes being ignored, it can also result in the confusing situation where your modification is sometimes ignored, and sometime used. This optimization can, for instance, be used inside the ctors and dtors of a given class, because inside those functions, that class IS the most-derived type, even if they're being invoked as part of the construction of a more-derived class. It can also be done anytime an object has a fixed type, rather than being accessed through a pointer or a reference. It can even be used when accessing an object through a reference or pointer, if the implementation knows that the reference or pointer will always refer to an object of a specific most-derived type. That can be easy to determine if the object's definition is in the same translation unit as the code that accesses it by reference. Some modern implementations can even determine that at link time by looking across two or more translation units. That's just one optimization that I happen to know about - I'm sure there's many others I didn't think of. |
Scott Newman <scott69@gmail.com>: Jun 08 10:11PM +0200 >> The whole thing is predictable since no compiler behaves differently >> than cfront. > Prove it. There's no need to prove it. ABIs like COM f.e. rely on that. |
Scott Newman <scott69@gmail.com>: Jun 08 10:13PM +0200 > would result in your vtable modification sometimes being ignored, it can > also result in the confusing situation where your modification is > sometimes ignored, and sometime used. Then you assign the object-address to a volatile pointer and that to a non-volatile pointer. The compiler wouldn't be able to cache any virtual functions across that assignemnt. |
Scott Newman <scott69@gmail.com>: Jun 08 10:14PM +0200 >> There's no reason to do it differently than Cfront. > Thank you for confirming that you're just assuming it without any > verification. There's no need for verification since what I said is obvious. |
StuartRedmann <DerTopper@web.de>: Jun 08 10:15PM +0200 On 08.06.20 15:13, Frederick Gotham wrote: > obj.SomeFunction(); // Make sure compiler doesn't hardcode func address > } > } The following may work on your machine. It assumes standard vtable layout (vtable starts at object's address), sorting of vtable entries is not relevant as this example uses only a single virtual method: class Base { public: virtual void callme() = 0; }; class Foo : public Base { public: virtual void callme() { std::cout << "Hi, I'm Foo."; } }; class Bar : public Base { public: virtual void callme() { std::cout << "Hi, I'm Bar."; } }; int main() { Foo foo; Bar bar; Base* base; base = &foo; base->callme(); base = &bar; base->callme(); // The following results in undefined behaviour!!! // Tested only with Apple LLVM 7.3.0, but should work with // a number of other C++ compilers, too. void** vtableFoo = reinterpret_cast<void**>(&foo); void** vtableBar = reinterpret_cast<void**>(&bar); std::swap(vtableFoo[0], vtableBar[0]); base = &foo; base->callme(); base = &bar; base->callme(); } Note that the ordering of the virtual methods in the vtable differs greatly between compilers. IIRC, Borland C++ used to sort the methods alphabetically, whereas MS C++ compilers used to sort them in the order in which they appear in the class declaration. To my knowledge that was the main reason why Borland C++ had to use the C headers for working with COM (component object model) objects. I trust that you are trying to reverse engineer some code, or you are doing just some proof-of-concept stuff. As all the others have stated quite clearly, fiddling with vtables is quite dangerous. Regards, Stuart BTW: As an old Objective-C programmer I quite like the feature to change a class'es behaviour during run-time. In contrast to C++, changing the Objective C equivalent of a virtual method is directly supported by the language. |
Scott Newman <scott69@gmail.com>: Jun 08 10:15PM +0200 > Of course there are good reasons to do it differently - optimisation. > That is why any good compiler will de-virtualise calls when it can, > skipping the use of a vtable. Then you assign the object adress to a volatile pointer so that the compiler is inable to say if the object behind that pointer might have changed. |
Scott Newman <scott69@gmail.com>: Jun 08 10:18PM +0200 The issue you might run in here is that the vtable lies in a non-writable page. So you would have to allocate a completely new vtable, copy the contents of the old vtable there and implant a new vtable-pointer on the objects starting adddress (or at the address before the first data-member if the object has derived from a class without virtual functions). That's professional programming since this is 100% portable and reliable. |
Scott Newman <scott69@gmail.com>: Jun 08 10:20PM +0200 > in which they appear in the class declaration. To my knowledge that was > the main reason why Borland C++ had to use the C headers for working > with COM (component object model) objects. Not true. Borland C++ is C++-COM-compatible. |
Christian Gollwitzer <auriocus@gmx.de>: Jun 08 10:21PM +0200 Am 08.06.20 um 19:40 schrieb Bonita Montero: > Use non-virtual functions which dispatch according to your > own virtual function tables. +1 I think, this method is described in this talk, where you implement your own vtable: https://www.youtube.com/watch?v=gVGtNFg4ay0 Christian |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 08 01:24PM -0700 >> Thank you for confirming that you're just assuming it without any >> verification. > There's no need for verification since what I said is obvious. Then there's no need for anyone to reply to you. Bye. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
Scott Newman <scott69@gmail.com>: Jun 08 10:25PM +0200 >> There's no need for verification since what I said is obvious. > Then there's no need for anyone to reply to you. Bye. You're right. Because I'm correct there's nothing more to say. Bye. |
Frederick Gotham <cauldwell.thomas@gmail.com>: Jun 08 01:27PM -0700 I have the machine code of the program I want to alter. I don't have the original C++ code for it however I worked on it before and so I have a vague recollection of how it works. The first thing I will do is search through the machine code for direct calls to the function which I intend to hijack (i.e. I will search for where the vtable accessing has been optimised away). I will replace these direct calls with actual use of the vtable. (There might not be any direct calls). Next I will take the machine code of an existing interrupt routine and run it through a decompiler; I will add my own code for altering the vtable, and then I will compile the interrupt routine again and slot it back into the program. (I actually might not need to use a decompiler if I simply append my own machine code). Testing will be very easy: It will either work or not work. What I am proposing is an alternative to re-writing the original program, at a cost of a few thousand man-hours. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 08 01:20PM -0700 > The wording actually used, however, allows other possibilities, such as > # define errno (*__errno_location ()) > which is how errno is defined in /usr/include/errno.h on my system. In fact the C standard has required errno to be a macro since C89/C90. I'd say that this statement in POSIX: It is unspecified whether errno is a macro or an identifier declared with external linkage. is an error (though a fairly minor one) and that sentence should be deleted, and the preceding sentence: The <errno.h> header shall provide a declaration or definition for errno. should be updated to state that <errno.h> shall provide a macro definition for errno. (POSIX apparently goes back to 1998. I wonder if that wording was based on an earlier draft of ANSI C and never updated.) -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 08 01:25PM -0700 On Monday, June 8, 2020 at 2:21:53 PM UTC-4, Bonita Montero wrote: > > Because errno is defined as a macro. > I "compiled" just with preprocessing-output and > errno is not substituted but stays as errno. The simplest and most reliable way to determine whether errno is a macro is #include <cerrno> #ifdef errno It's permissible for a macro named errno to have an expansion that is also errno. Such an expansion would not be infinitely recursive - the rules for macros are designed to prevent such things. However, if it is #defined that way, then errno must also have a non-macro declaration. In that case, if ::errno doesn't work, that implies that it's declared in some other namespace. I'd recommend determining the actual file that is being used (gcc's -E option can be useful for that), and then looking in that file to see how errno is actually #defined by your implementation. |
rick.c.hodgin@gmail.com: Jun 08 12:16PM -0700 On Monday, June 8, 2020 at 8:09:19 AM UTC-4, Mr Flibble wrote: > Assertions made without evidence can be dismissed without evidence. I write this not for Leigh Johnston, but for others who would read his words and place any value on them. ----- What is the evidence one person loves another? They don't turn purple or start growing a new appendage when they're in love. There's nothing outwardly provable. Even the release of chemical markers do not prove it's love. Could be another cause or trigger. The only evidence comes not from the assertion, but the observation of the thing, and the coupled ability to reason and conclude that "that behavior" indicates "that emotion" and that it doesn't come from feigning or deception. Continued observation and reasoned evaluation bears it out. As to God and God's design: There is evidence all around us. The geologic column is not millions of years, it's hydraulic sedimentary depositing from the flood. And the fossils we find of dinosaurs with blood vessels, blood cells, and other soft tissue still in tact, some with DNA fragments also still in tact, indicate the "millions of years" conclusion cannot be true. Couple that to fish fossils found in the highest mountains, and pre- flood fauna being found in Antarctica, and it all adds up to a new narrative where observation and reason cast out the old narrative and speak to a new one. Look at the complexity of DNA. There is no way that just happened. Clearly one of the best evidences of design: DNA replication. One strand goes forward, one is stitched up backwards in segments: https://m.youtube.com/watch?v=7Hk9jct2ozY&t=0m53s God teaches us the truth. Ask Him to teach you. -- Rick C. Hodgin |
Juha Nieminen <nospam@thanks.invalid>: Jun 08 07:59PM > gift of salvation today. You are not promised tomorrow. But He > does promise eternity for all who recognize their sin, repent, and > ask Him to forgive them. I think it's rather hilarious that you think that you are not speaking incantations and spells, but that's exactly what you are doing, even if you lie to yourself that you aren't. You believe that your god is acting on people through his words, which you are reciting. That the words of your god have the power to influence people, to turn them to him and to save them. That by you speaking these words, god is affecting people. That's the very definition of a magic spell. That's exactly what you are engaging in. You are just unwittingly engaging in sorcery, even if you don't realize it and you vehemently deny it. (Well, *trying* to engage in sorcery, of course. Nothing of that has any supernatural effect on anything. But whether it has real power or is just in your imagination, it's still essentially a spell that you are trying to do.) Your very scriptures condemn sorcery, incantations and spells, but you are, ironically, engaging in them yourself. You believe that the words you are saying may supernaturally have an effect on people. In other words, it's a spell. It's sorcery. Deny it all you want. It doesn't change the fact. |
rick.c.hodgin@gmail.com: Jun 08 01:22PM -0700 Juha, It's understandable to think that way because the nature of God is spiritual, and the natural man has no faculties to discern things of the spirit. It is, therefore, impossible for the natural man to know the difference between sorcery and the Holy Spirit of God. The differences exist, and the teaching here is that it's available to everyone who will press in to God seeking the truth. I do not give to you salvation. The full weight of my message is to point to you the One who does give salvation, and to teach you of His existence and what He offers. You owe it to yourself and others to investigate it with a truth-seeking heart. -- Rick C. Hodgin |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 08 07:56PM +0100 Scott Newman <scott69@gmail.com>. Who the hell is this guy? Is he for real? /Flibble -- "Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin "You won't burn in hell. But be nice anyway." – Ricky Gervais "I see Atheists are fighting and killing each other again, over who doesn't believe in any God the most. Oh, no..wait.. that never happens." – Ricky Gervais "Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Byrne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?" "I'd say, bone cancer in children? What's that about?" Fry replied. "How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil." "Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say." |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 08 10:06PM +0200 On 08.06.2020 20:56, Mr Flibble wrote: > Scott Newman <scott69@gmail.com>. Who the hell is this guy? Is he for real? What makes you sure that the person is a "he"? :) - Alf (and no it's not me, but same newsreader, OS and posting server) |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment