CppCast - Intel Tamper Protection
Episode Date: January 21, 2016Rob and Jason are joined by Marc Valle to discuss Intel's Tamper Protection Toolkit which can be used to protect your C++ application from reverse engineering and tampering. Marc Valle is the ...technical lead for the Intel (R) Tamper Protection Toolkit. His professional interests include tamper protection, reverse engineering, compilers, security, and privacy. In his free time he can be found staring at the black line at the bottom of the pool preparing for his next competition. News Compilers targeting C Lambdas are dangerous? VS 2015 Update 1 New Experimental Feature MPX Links Intel Tamper Protection Toolkit Intel Tamper Protection Toolkit Getting Started
Transcript
Discussion (0)
This episode of CppCast is sponsored by Undo Software.
Debugging C++ is hard, which is why Undo Software's technology
has proven to reduce debugging time by up to two-thirds.
Memory corruptions, resource leaks, race conditions, and logic errors
can now be fixed quickly and easily.
So visit undo-software.com to find out how its next-generation
debugging technology can help you find and fix your bugs
in minutes, not weeks.
Episode 42 of CppCast with guest Mark Vallee, recorded January 21st, 2016.
In this episode, we talk about transpiling to C and C++.
And we'll talk to Mark Valley from Intel.
Mark will talk to us about protecting your application code from tampering. Welcome to episode 42 of CppCast, the only podcast for C++ developers by C++ developers.
I'm your host, Rob Irving, joined by my co-host, Jason Turner.
Jason, how are you doing today?
I'm doing all right, getting over a cold.
Hopefully I don't hack and cough too much into the microphone for today's episode, Rob.
Yeah, my whole family is getting over something as well.
I think I'm okay today, but my daughter actually had pneumonia right after last week's episode. So we all kind of
caught something after that. Oh, that's unfortunate. Yeah. Yeah. Very unfortunate.
Well, at the top of every episode, I like to read a piece of feedback. This week I got a tweet from
my developer day and he wrote in saying he just finished listening to every back episode
and now he needs us to up the frequency to two a week you've made my journey to work fun so jason
i don't know how you feel about this but i'm not sure if we would ever uh be able to handle two
episodes a week two a week does sound like a bit but if they want us to keep up the frequency
more of our listeners need to send us potential guests.
Yeah, that's a good point.
Yeah, it's interesting because when we first started, there was some actual bits of feedback saying like, oh, can you guys really keep going at one a week?
And I'm happy to say we're able to.
Mostly, yeah.
Yeah, we just missed a couple weeks here and there.
But two a week, I just don't know how we could get out that much content uh with our focus on just c++ but yeah thanks for the suggestion and like jason said
uh we were definitely always looking for guest suggestions so feel free to send us those over
facebook twitter or you can email us at feedback at cppcast.com. And don't forget to leave us a review on iTunes as
well. So joining us today is Mark Valli. Mark is the technical lead for the Intel Tamper Protection
Toolkit. His professional interests include tamper protection, reverse engineering, compilers,
security, and privacy. In his free time, he can be found staring at the black line at the bottom of
the pool preparing for his next competition.
Mark, welcome to the show.
Thanks, guys. Good to be here.
So what kind of swimming competitions do you participate in?
Master's level.
So, in fact, just this summer I got back from – I went to World Snatch in Russia, in Kazan.
So the cool thing there is they've aligned that now with, um, the Olympic worlds.
So essentially,
you know,
we got to see like Ledecky break the records and stuff like that.
And then we swam the next week.
So it was pretty cool.
Um,
great experience.
I've been to Russia before for work,
but this was the first time it was purely,
you know,
for fun,
ate a lot of great food.
I also made some stops off in Estonia and Finland,
which I'd neither of which I had been to.
So that was pretty fun.
Wow, sounds like a great trip.
It was.
Okay, so before we start talking about the Tamper Protection Toolkit, we have a couple news items to go over.
And Mark, feel free to jump in on any of these.
This first one is an interesting list that you found on GitHub, Jason, of different compilers or transpilers that target C and C++ code.
Do you want to do a little more of an intro for this, Jason?
You know, it's like this interesting kind of brain candy for me
to look at all these things.
There's basic compilers and Lisp compilers and Python
that all take your Python, Perl, whatever input and generate C or C++ code from it.
And it made me just wonder, like, I wonder if there's anything that could really, like, be an advantage in your project base to write some of it in Python, have it translated into C++, and then compile it all as your C++ project.
I don't know.
Yeah, some of these are kind of really off-in-the-weeds languages
I've just never heard of.
I don't think
we've been cursing at all in the show, so I
hesitate to drop
one, but there's one called BrainF,
and you've probably
heard of it, which is a language that just
consists of punctuation, really.
And apparently you can transpile that
into C, which is interesting.
Are there any other kind of cool ones
you wanted to bring up?
I noticed that one of the Python compilers...
For me, it certainly makes a lot of sense.
Yeah?
I mean, it's a lot easier to sort of predict,
you know, in my mind,
what the compiler is going to do,
what code is going to be generated
at at least assembly level from C code as opposed to some weird language.
So getting it into that form first can be super handy.
The major downside I see potentially to this is having to debug what the compiler is outputting along the way too.
So some of these are relatively small, unknown projects.
That's a good point. Okay, well, this next one is an article,
just a post on Reddit,
talking about a trend with lambdas
potentially being dangerous
when they're included in the header file.
Jason, did you want to go over this one too?
Sure.
So in C++, there's this thing called odr
the one definition rule if anyone's not familiar with it saying that every uh object basically or
what's a good way to put it function instantiation has to have exactly one definition in your code
base right in the compiled object but if you use a lambda and pass it to a template,
you risk having multiple things that do exactly the same thing from different translation units
but have different implementations
because each lambda, by definition, is a different type.
It's kind of esoteric, but it's also interesting
because lambda is getting a lot more use now,
and I'm wondering where this is going to go.
One interesting thing that came up
in the discussion on Reddit was
John Caves from Microsoft
joined the conversation
and says that
yeah, there might be a bug in
MSVC's
handling of this, and he's going to
look at fixing it for the next version.
Yeah, and there's some discussion about whether the standard itself needs to be
updated to deal with this problem too.
Right.
Mark,
was there anything you wanted to add on this one?
The standard is tough for me.
Yeah.
I don't follow the standard that closely,
honestly.
Okay.
Well,
this last article is actually also coming from Intel, Mark, and this is
Visual Studio 2015 Update 1 added a new experimental feature called MPX, which is
Memory Protection Extensions. And there is an article here with a little tutorial on how you
can go about turning on MPX, which looks like it basically will check for buffer overflows for you.
It is somewhat limited to you have to be on the latest and greatest Windows 10 version,
and you need to be using a fairly new Intel processor.
Mark, is this something your team works on?
Well, this is not something that we work on
ourselves. Intel's has a pretty big, you know, company, also a pretty big software organization,
but you know, this is definitely something we're really excited about. Generally, you know, one of
the things we're always trying to put new stuff to help developers in our chips, but ultimately,
if there's not tools to support the support them, or sometimes operating systems to support, you
know, the end user doesn't see that or the end developer doesn't.
So we're really excited to see that Microsoft is providing the first support
for this. So again, you know, to make this work, you will need, um,
windows 10 and a sky lake, which is the latest generation of the, um,
the processors. But the cool thing is when you have those, um,
you'll be able to, even if all your customers don't even locally on your
machine, you can use this for debugging things.
It's just another way to see if things go out of range or stuff like that.
There's also currently Linux kernel 3.19 and GCC 5 also support this as well.
So if you're doing development on those compilers and operating systems, you'll be able to take advantage of this on a Skylake.
Interesting.
Okay, yeah, you just answered my next question, if there are going to be any GCC or Clang support for this.
Yeah, I don't know about Clang,
but I know GCC as a 5 already supports it.
But you need a Linux kernel 3.19
because it's a combination of kernel support.
You know, there's a runtime library.
There's a few things that work together to make this work.
Okay.
So let's get started talking about the project
your team works on at Intel,
which is the Tamper Protection Toolkit. Can you give us an overview of that?
Yeah, sure. So the top-level bullet points is you can use it to protect application code against reverse engineering with the obfuscating compiler that comes with it.
It can also, it'll sort of create a runtime software-protected execution environment where you can do sensitive operations that are a little bit harder to observe and also modify.
In addition, it can help monitor software and code
from tampering at runtime.
So let's say that someone tries to jam a branch
and change a check, like an if, to something else.
We can detect that at runtime and prevent,
let's say some virus or worm
is trying to change some of your code.
That can be detected at runtime
and prevent that from happening.
You can also use it to secure some kind of assets in your code,
such as maybe if you have keys or passwords in the code,
you can protect them in a similar fashion.
So if someone does actually try to modify your binary
that's been protected, what happens?
Well, that depends on which binary.
So there's two main components in the tamper protection toolkit.
One of them is something we call IProt,
which is our obfuscating compiler.
Essentially, it'll take a shared library input,
let's say a DLL or an SO,
and it'll create a self-encrypting and self-modifying equivalent output code
that's harder to reverse and tamper with.
So that's one component.
So if someone were to modify something in there,
essentially what would happen is it would lead to your program
failing to execute.
It would typically crash.
There's a second component as well
that's called Code Verification Library.
And what that can check is you build that into,
let's say, something that's protected by IPROT,
and it can check other bits of code in the system.
Let's say just a general SO or DLL that you have.
That could be C++ or whatever.
And if someone tampers with that,
a check from within the portion protected from IPROT can detect tampering.
And if it's tampered with, then you can take a specific action
that's not just crashing. I mean, you could fail in a more graceful way, then you can take a specific action that's not just crashing.
I mean, you could fail in a more graceful way, or you can detect it and do some different
activity. So depending on how you engineer your security solution, you have a couple options.
Interesting. So you keep referring to it, I'm sorry, as a compiler,
but it starts with object code. Is that correct? Not with source code?
That's correct. So the typical use model for at least the IPROT portion of the code is you would build an SO or a DLL, and you would pass that SO or DLL to IPROT along with the entry point, but essentially it's self-encrypting, self-modifying code. So what we do is essentially we start from that entry point,
we disassemble the code,
we go through all possible code paths,
take it into an internal representation,
and then modify it in such a way that, you know,
it's harder to tamper with.
So it's not just the entry point that you specify,
it's anything inside that DLL that that entry point also references
will also be protected?
Exactly.
Okay.
Right, all code paths starting from that entry point. So also, interestingly, obviously, if any code paths that aren't reached there just never
get sucked in. So, you know, if you have 10 entry points and a bunch of other codes
sitting there and if they're never called from the one you pass in, they never even get included
in the final binary. Interesting.
I wanted to interrupt this discussion for just a moment
to bring you a word from our sponsors.
Do you hate it when your customer
finds a bug in your code? Tired of
spending ages trying to reproduce intermittent
failures? At Undo Software,
they know that debugging C++ can be hard.
That is why their next-generation
debugging technology for Linux and Android
is designed for C++ users
and is proven to reduce your debugging time by up to two-thirds. Embed live recorder within your programs Thank you. Corruptions, resource leaks, race conditions, and hard-to-find bugs can now be solved quickly and easily.
Visit undo-software.com for more information and start fixing bugs in minutes, not weeks.
There's something on the fax saying it works with C and non-polymorphic C++ assembly.
What exactly do you mean by non-polymorphic C++?
All right, so first of all,
what the fact means there is that's specific to IPROT.
So code verifies,
you can verify and protect from tampering
things that are pure C++ with no restrictions.
However, the things that are protected
specifically by IPROT,
which are also obfuscated,
that also go into this protected environment,
those things have some limitations.
The basic limitations are
the code cannot have relocations.
It can't have indirect jumps or indirect calls.
And so in C++, if you're doing something with polymorphic classes,
you're going to have a V table.
And so it's going to have a call through a pointer.
And so at compile time, we can't disassemble your binary
and figure out where that's reaching.
So in other words, if it's calling some virtual function,
we don't know where that is at the time that we're scanning the code,
or at least we can't figure that out now.
It's hard to figure out.
Theoretically, with some data flow analysis, it could be possible,
but we don't have that support yet in our code.
So that's what we mean by non-polynomorphic C++.
If you use C++ that doesn't have relocations,
doesn't have indirect calls and jumps,
then it will process it.
So if IProt would work,
but it wouldn't protect everything that the user might expect it to protect
because you couldn't trace all the way down.
Right, but it wouldn't exactly.
IProt would fail to essentially process it
because essentially what we're trying to do
is you emit equivalent code
that functions the same as the input,
but if it can't trace down, it's going to say,
it's going to get to that code,
and it's going to get to this indirect call,
and it's going to say, I don't know what to do here, error.
So typically your use, your typical use case of this is
you would refactor your code if it was C++.
Generally what we do ourselves is we just refactor it to C.
I mean, we don't put all our code into the IPROC code.
We put the things that are sensitive typically into it. So typically what we'll do is we just refactor it to C. I mean, we don't put all our code into the IPROC code.
We put the things that are sensitive typically into it.
So typically what we'll do is we'll find, you know, the bit of code that we want to protect, the sort of root of trust,
we put that into, you know, like a C module.
And then from that, we spider out with code verified to detect tampering.
So things that need to be protected from observation,
we put inside the C module.
And things that just need to be protected from tampering,
we'll often put inside these C++
components that are outside of it.
Okay.
Now, you talked a little bit about protecting certain assets.
Is that part of IPROT, or is that kind of from the rest of the toolkit?
Well, it's both.
So IPROT will protect assets from being both observed and modified so the assets can code. So let's say, again, you wanted to have some simple encryption or something and you wanted
to embed a key.
I'm not suggesting this is the best way to do something, but let's say you want to embed
a password into your code for some reason.
If you wanted to do that, you could embed the password into, let's say, a constant static
in your code in IPROP, or in your DLL, let's say, and then process that through IPROP.
And when you do that, the way IPROP works is, if it didn't do this, I should say,
you could just take a disassembler, do a dump bin, take a look at the binary,
find the string, real easy.
If you pass it through IPROP, it's much more challenging for an attacker
to be able to extract that string or password or whatever. So that would be an example of how
you can protect an asset with iPod from observation. You know, if you don't mind,
if I go back for just a second, if you can protect anything that's C or assembly, you can
certainly do things that behave like virtual table calls in C or assembly like C++ does.
So can you encounter the same kind of failures in those languages?
In C, absolutely.
So if you essentially write, so again, if you were to write something that is a call
through a pointer in C, then we would essentially flag an error, say, hey, there's an indirect
call here.
So yes.
Interesting. So we talked a little bit about C and C++.
Does iProt
work with other compiled languages,
like Fortran?
So, we've not validated it with that. I mean, in theory,
any image, any fully
linked binary image that you can emit
that doesn't have any indirect calls,
indirect jumps or relocations, we can
theoretically process it.
It kind of sounds like, do you, I'm sorry, go ahead.
But we haven't validated that, obviously.
Okay.
Do you rely on the C-A-B-I in some way,
like being able to look at function call names
and that kind of thing,
since you have to provide an entry point?
Only for that.
Actually, it's not really the C-A-B-I so much
as just the symbol table that we look at in the image.
So we are relying on like the SO format or the DLL format.
I mean, the way we require it is we actually require the entry point to be an exported function.
So we don't have the capability right now to give internal functions that aren't explicitly exported by the DLL or the SO.
Okay.
Okay.
So what operating system does this work on currently?
So the tool itself works on Windows hosts only.
Currently, the targets can be Android or Windows.
Oh, okay.
In theory, I mean, I suppose Linux would work,
but, I mean, we don't advertise that
and we don't officially support that.
But certainly, you know,
internally we've had it work just fine on Linux SOs.
Okay. Yeah, I was wondering about that, because isn't an Android library very similar to a
standard Linux SO? Yeah, very similar. In fact, you know, early on, we actually
used, you know, Linux to do some of our validation before we actually were validating on Android. But
again, according to the official support, it's Android and Windows.
Do you have plans to officially expand that support?
Yeah, I mean, I think that it's primarily going to depend on customers.
I mean, I think that primarily what we're targeting right now is those developers that
are targeting Android because they have some in the mobile world and stuff like that.
There's a lot of interest in protecting assets you put up on the App Store or whatever, or
Google Play or whatever.
But certainly if there
was some request for that
from customers, that's certainly something we could really
easily do. We're just sort of looking at the market
right now. We're in beta.
That could certainly be, if a lot
of people clamor for that feature, it's certainly something we could do.
So currently
it is a free tool, correct?
Right. The current beta right now is free.
There's a link you can download.
It's Intel Software Tamper Protection.
I believe we can provide a link with the podcast or whatever.
Yes. Yeah, we can put one up on the show notes.
Okay.
Yeah, the current version is free.
Do you know if that's going to change when you come out of beta?
I don't know for sure.
My understanding, I mean, a lot of it depends on sort of what the business side, you know, wants as a goal for this.
My understanding is it will be charged for a fee product once it's released.
But that's not officially decided yet.
I think that's still to be seen.
Okay.
Are there any downsides to using the protection toolkit, like a performance impact, anything like that?
Yeah, absolutely. Are there any downsides to using the protection toolkit, like a performance impact, anything like that?
Yeah, absolutely.
I mean, obviously what's happening when this thing is running is we have self-encrypting, self-modifying code. So as it's operating, some small portion of the code comes in the clear and everything else is encrypted.
And then the next phase of execution, that port being encrypted and something else becomes decrypted.
And so obviously this is a performance penalty.
And that's tunable with options to the tool.
So you can decide how frequently it mutates, how frequently these transformations occur,
how big the window is, when they happen.
So hopefully if you have a performance sensitive section of code, you're not going to do a
lot of mutations in a very tight loop.
So we give the capability to the developers to sort of tune that.
But it's certainly a key aspect of actually deploying this in a real solution is
you want to, you know, understand the security versus performance trade-offs because you can
make it very secure, but that can kill your performance or, you know, you can make it
very performant, but you have a lot less security benefit.
So you've mentioned several times that it's self-encrypting, self-modifying code.
Do you have any problem with virus scanners on Windows host
flagging your binaries as doing bad things?
So we haven't really run into that yet.
However, we can certainly imagine that being an issue.
And in fact, we are working with some antivirus vendors
on technologies to mitigate or minimize that sort of impact to our customers.
Something like saying, hey, this is something that's protected with iProt.
And as a result, or as an Intel tool, so as a result, if you see this, just heads up.
Interesting.
Bring it back to Android for a moment, since that seems to be one of your primary targets.
Is it only Android x86, or is it Android ARM as well?
We only support x86 or is it android arm as well we only support x86 right now so okay currently um you know it's
very dependent on the instruction set that you know it's obviously we have to do a disassembly
and stuff like that in theory you know sometime in the future you know we could potentially make
arm work i mean one of the issues with arm besides just the instructor set obviously is we have to be
able to support self-modifying code and due to the way the caches are set up in android or not
android sorry in an arm that may be a little bit of a challenge but you know for now currently x86 code and do the way the caches are set up in Android, or not Android, sorry, in ARM,
that may be a little bit of a challenge.
But, you know, for now, currently x86 only.
Yeah, it does sound highly CPU architecture dependent, like it would be a complete rewrite almost for another CPU architecture.
Well, not necessarily.
I mean, again, not to get into too many details, but a lot of the parts of the technology have
nothing to do with the specific instructions.
I mean, we have, you know, actually
the tool itself is written in C++
and, you know, there's a lot
of things that have to do with, you know, graph
manipulation and stuff like that and
matrix multiplication and, you know,
you know, Feist stone networks and stuff
that are completely unrelated to the instructions.
The components that do the reading and the writing
of the instructions are a relatively small portion
of the overall code.
Okay.
Okay.
Is there anything else we're missing that we haven't brought up yet, Mark?
Well, besides the website, there's also some pretty cool tutorial video up on that website that I think I can give you guys a link to.
You can sort of attach.
It's a quick, you know, like sort of a hello world for the tool.
And so it'll basically show you, you know, like in, I think the example is like in Visual Studio, you go quickly and, you know, create a simple, you know, obfuscation or whatever of a really small bit of sensitive code.
So it's kind of nice to look at it.
I think it's something like five or six minutes long.
It sort of gives you a feel for how it's used in practice.
Right.
Yeah, we'll definitely include that link in the show notes.
Since this is a C++
podcast and you said the tool is
actually written in C++,
are you guys
doing anything cool with C++, pushing
the language in any interesting ways to write
this project? Well, I don't know
so much about pushing the language. I mean,
we're trying to be, you know, I try to be really
cautious. I mean, there's some really great things about,
so a lot of C++11, certainly,
a lot of the great, you know,
it's very strongly more in that style.
Very low on lambdas and things like that, generally.
I mean, we try and, you know,
things that are really nice features,
but things that are also easy to grok
for the people reading it.
I mean, my experience is that things like lambda are great for the person easy to grok for the people reading it. I mean, my experience is that things like Lambda
are great for the person writing it
and horrible for the person reading it in a lot of
cases. So, you know, we don't want to do
write-only code. But certainly one of the
things that we do rely on a lot is
some of the
BGL stuff is one of the things that we rely
on. The Boost Graph Library
for GraphQL, since there's nothing
in the standard library for that.
So that's certainly very handy
for some of the control flow representations that we have.
Interesting.
Do you have any particular then pet peeves?
You mentioned lambdas.
Anything that you're like,
man, I wish this would just remove from the language altogether?
I wouldn't say that.
I mean, I think that a lot of things that I like about the language
or at least I really like what C++11
did to the language
there were a lot of problems before
with sort of the idioms
for memory management and I think a lot of the
using a lot of the
things like the unique pointers
and things of that nature have really made the code a lot clearer and easier to follow.
So I'm sort of happy with where things are now.
But I wouldn't say that I'm sort of a language wonk in that area.
My area of expertise is much more in the – and further down in the machine, obviously, in the assembly sort of translation level.
Okay. down in the machine obviously in the assembly sort of translation level okay one question i i had
back to you know the actual software tool if you're not using something like this how easy
is it to kind of decompile code and be able to extract someone's uh you know potentially valuable
assets out of their compiled code if you if you no protections at all, if you're just writing just code,
just normal C code with nothing,
no thought to this at all,
it's basically trivial.
I mean, you can do an obj dump on it
and you can just look in the string section of the code.
I mean, you can do a little bit yourself.
I mean, certainly you can do some crazy
sort of algorithms in your code
and then you can grab sort of one byte from an array somewhere
and one byte from somewhere else and do some math in your code to do that.
And so that's, you can certainly bake your own thing there.
And, of course, that only protects, you know,
from seeing what's going on to a certain level,
but it certainly doesn't help you if someone tampers with your code.
Like if later you have like a check versus like a password or something,
like if the password is X, do this or whatever,
someone can easily find that if check and just change it to, you know,
from an equals to a not equals in the assembly, change a byte
and bypass any checks that you have.
So let's say you're writing maybe something for
a POS terminal or something. It'll be relatively
easy for what someone gets their hand on it to get a little
worm or a virus to land on that POS terminal and modify some code.
With some more advanced protections,
you can make it much harder for them to do something like that,
especially if something is dynamically changing.
It makes it much harder for them to do that sort of attack.
Well, the attacks that we've heard of recently where stores,
I mean, you bring up POS systems where credit card readers
and processors themselves
have been compromised and shipped to stores.
It sounds like something like this is going to become that much more important that developers
start using it.
Right.
I mean, this is not, again, it depends on your use case and your threat model, right?
And obviously, this is one of, among many layers of defense in depth.
I mean, this is obviously not Fort Knox-level security.
Certainly, there are things we have coming down the road in hardware
with some Intel processors, starting with Skylake and SGX,
the software guard extensions technology that really give you a hardware-trusted execution environment.
The primary challenge there is that those things aren't going to be ubiquitous
across all hardware platforms for some time until everyone upgrades to those or later.
So until then, as developers, we still want to be able to deploy software
that we can have some assurances isn't being tampered with
to a lot of customers that don't have that latest hardware.
And so that's where Temp Protection Toolkit really comes into play.
Right.
Okay.
Well, I think that might be all the questions I have for you, Mark. Jason, do you have anything else? No, I don't think so. Okay. Well, I think that might be all the questions I have for you, Mark. Jason,
do you have anything else? No, I don't think so. Okay. Mark, is there anything else you wanted to
share? Any more links to the website or just instructions on how people would get started
using the toolkit if they're interested? Well, I think the website links are probably going to
help you out a lot. I mean, sort of as a general thing, we're definitely just in general,
Intel definitely looking for people with software expertise and, you know,
deep language expertise.
You know, unfortunately, we find more and more in sort of like universities and stuff that there's a lot of, you know, higher level languages like Java
schools and things like that where, you know, they're great for developing
applications, but we find that a lot of people don't understand how the
underlying machine works because they don't have to deal with things like
memory and pointers as much.
Definitely, for those people out there
who are looking
potentially at a software career,
do take a look at the jobs at
Intel because we are looking for people with
good expertise and good background
in software. It does seem like
universities are not teaching C++ as much
as they should be these days, which is a real shame. More from the sound of it.
Assembly. Yeah. Or just how the machine works in general.
I understand. A lot of it, they're advertising, create an app
or something. That's great and all. I'm sure there's a great
market for that and there's a need for that. But certainly for the kind of things, the problems we
want to solve at of at Intel,
understanding of sort of the underlying
machine and not just C++, but you know,
C++ helps, C, C++, assembly,
any of those languages will
get you on sort of that track to know what's
going on under the hood.
Right.
Okay. Well, Mark, thank you so much for your time
today. Right. Thanks for having me, guys.
Appreciate it. Thanks for joining us. Thanks so much for your time today. All right. Thanks for having me, guys. Appreciate it. Thanks for joining us.
Thanks so much for listening as we chat about C++.
I'd love to hear what you think of the podcast.
Please let me know if we're discussing the stuff you're interested in,
or if you have a suggestion for a topic. I'd love to hear that also.
You can email all your thoughts to feedback at cppcast.com.
I'd also appreciate it if you can follow CppCast on Twitter and like CppCast on Facebook.
And of course, you can find all that info and the show notes on the podcast website at cppcast.com.
Theme music for this episode is provided by podcastthemes.com.