Monday, June 8, 2020

Digest for comp.lang.c++@googlegroups.com - 25 updates in 4 topics

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: