I'll tell you how your feedback influences the course, which is that in all the notes that I put so far, there's a lot of content that we don't quite get to. I always have this choice of skip over it or keep saying it, say like, here's the most important thing to get across today, Wednesday or something or whatever. Here's like the mastery task. How do we feel about that? Mastery had a choice today for basically, I want to go through the eight programs and we're going to reverse them. Unlike the flag, the crack means from Wednesday, these are common like code crap, right? Four loops and ors and if statements and fizz buzzes and stuff or whatever. And we're going to get, we're going to look at them and see if we can't figure out the pseudo code of what they must have been doing on the other side, because that's master desk, right? It's like given a binary, can you see the intent of the human on the other side of it? Right. That's the goal. I wanted to do a little bit more of that, honestly. If you solved the PCP four now I CC or whatever, then maybe you don't need this, right? And so I could move on to my next topic or whatever which is master. But I looked in the discord, I looked at these mastery checkpoints and it's still more red than green right here. Seeing that, it's like, all right, cool. I'll take the slow path. Ever had that been more yellow and green, then I might have jumped to day instead of I'd go see starting Monday. Then just to say if ever you just have the thought cross your brain like, oh, I should update that or whatever, things like that, then only the first two are going to be relevant. You're probably not ready to perceive maybe my like Kansas City Chiefs. And then there was like a shooting at Kansas City Chiefs. And it's just like I felt like we did that like we talked about going there and hacking and stuff or whatever, and then there's crime happening there. And it's like, oh gosh, Did, is this a simulation? Are we like the players of the game? Anyhow, the fact that this is more red than yellow or green is why I'm doing the slow path today instead of the fast, fast, that's, that's on you, all right? Not really. But if I'm wrong, let me know if you are like, hey, I don't need to hear anymore about this, I'm good to go, which probably isn't everybody but some of you. Then I challenge you with what I said I would, which is write a flag cracker. Write a crack me, maybe tell us the flag format or whatever, something like that. Compile it, give us the binary and the discord. And then solve one of somebody else's. If you're so advanced that you don't need to hear this today and you're ready to be on a Monday topic or whatever, great, Write me a beautiful one of these, then an advanced kid for the rest of us. We'll take the slope back. Okay. All right, that's my little caveat because I was like very tempted to go and write more and more notes. Actually, we haven't done these eight, there's like eight things here we just need to do. That's the plan. Who? Okay, here we go. You're with me on the goal. The goal is to get the pseudo code out of these things, right? So what is the other side of this is the essence of mastery, task B, which is given a binary. Okay. That binary like I ran it without, like blindly. And, you know, generally don't run blind things that you've grabbed from a CTF or whatever. Fine. And it definitely would take an input. Yeah, not at all. All right, here we go. Unlike a crack me, there's no flag involved in this challenge. This is just like tell me what the coder did to make this. That's our job is it's a little bit more poetic, all right? Which means I don't need to run strings. It might help or not, but that's not the job. So we're going to jump into two Sein VP, Okay, this first one. What's my advice from last time? Check the calls, right? Go to the green things. In this case, we gets then a stack, check fail, and a red. Okay? All right, how much of this stuff at the top can we ignore? We'll talk a lot more about these first two lines. They happen in every single function. They've got nothing to do with the coder, right? We know that This guy, this word colon, you'll learn more about that in a minute or whatever. Totally ignorable. Okay, EAX or AX is just like setting the register to nothing. So what is this code doing exactly? Well, it's calling gets, can somebody, Google gets for me real quick. Okay, so it reads in a line from the specified input, which will be standard in. That's not a keyboard because we saw it, we ran it. It wanted to take input from my keyboard and then it stores it to a location, okay? So there is a location. What's the location that it wants to save to that we think we know? The first argument is supposed to be like where it's going to write to. We don't really know enough about calling conventions, but vaguely it's not like calling in Python where I can say like call parentheses a C. I've only got one op code to do my call, which means that the arguments are all the crap happening just above it. All right? So what's the crap happening above it? Well, I see a standard in, okay, some standard in address. Maybe I see the number 25. Probably if we kept reading that gets description, it'll say it'll read 25 characters from, not more than 25. Then what's the other value around here? It's actually this 130. What does var 30 H mean to you at this point? Okay. All right. That made you said 30 H is this guy. It's base pointer minus x 30. What is that? That's the cubby, the kindergarten cubby that I'm allowed to use for local variable. Whenever I see this like var 30, H's saying there's a local variable in the stack between the stack pointer and the base pointer. Where it's at the base pointer minus x 30. What's hex 30. All right, not enough people shouted that out. Do we need to do a little like hexadecimal 48? There you go. Good is three times 16. So like if this were just the number 30, this would be the number of ten. But instead, it's 30 hex, that's the number of 16. There's 316.01 that's how the hex works. Three times 16 is 48. All right. Fine. So that means that means that if this is the base pointer, the kindergarten teacher 48 cups to the left is where they're going to start writing things. How much are they going to write? They're going to write 25 characters. Okay, fine, that's all very technical. What do you think is the pseudo code that made this then? But a text editor, all right, includes standard or whatever inch, main void, some crap like this. The fact that it made space on the stack means that there is room for a string to be stored, in this case that is a buffer of 25 bytes or whatever or something like that, and then gets to the buffer 25 characters from standard in. That is my guess for the code that made the binary that we just saw. Okay. All right. So what is it doing? It's just reading input from the keyboard and storing it somewhere. And that's it as far as I can tell. All right, with me on that. Okay, that one's an important one to me because almost every time that we're doing one of these in like a CTF competition or something like that, they're reading input from the keyboard. And your job is to send malicious input, right? So you're going to recognize that input is coming from the keyboard a lot and it's getting written to a place. A lot like we're setting up to be able to start hacking these things and taking over the instruction pointer. But first begins like there is a stack and I'm writing to the stack and I'm reading things. Okay, cool. All right. Body language got a little bit mixed there or like a quarter of you were like, you know what if that's you ask questions, right? Just do some jumping jacks or something or whatever you like. All right? Or saying you're going too slow. You know, like I'm cool. Let's go to the next one. I did make these sequentially so we can build on the source code. Revenge to, shall I run at once? Revenge two. You can see that it's like pause, right? Like I ran this thing. Just pausing that. Is it waiting for input from the keyboard? That's a cool thing is hackers. Because you're like every time there's an F gets, it's like an automatic breakpoint. You don't even have to set a breakpoint. It's just going to stop there, right? So the code is going to flow instantly until it was hurry up and wait, that kind of thing. So we're hurrying up. Wait, we do something this time. There's one extra thing you wrote Blaw probably. That's enough that we can already like make the pseudo code. But look, we look okay. All right. What do we got? I see the same set up. You see the bar 30, all right? I see an F gets 25 characters, and that means that there's like some buffer. I ignore all the crap up to the FS. Maybe for now, until later. Now we have a new thing which is print F. What are they going to print F? We just above the print F must be the arguments of what's going to get printed F. There's two arguments here. One of them is this thing t wrote, That's a symbol. So they put a symbol for just like your string. If I'm coding something, let's go to my code. Here we go. Our prediction is something like this print you wrote. All right. Now the way print F works is it's a format string. And the format is going to read my other arguments to put crap in there. Percent is the format string for a. Then here I'd put buffer. All right? I think this is my pude. I'm saying this to iterate on a little bit of a concept, which is this, that string you wrote, percent. It's not a variable, right? It's not going to live on the stat at compile time. It's like, oh, and he made me a string, I need to save that somewhere. This one off value. If it's an actual string that might have some real size to it, the compiler puts it in a special little segment. I think it's called the BSS segment, but it puts it in this temporary global variable segment space. Let's take a look at that. That's what this is doing. You can even tell by the way that radar two is trying to describe the symbol to me. It's saying there's a symbol called you underscore wrote colon, underscore, underscore, underscore N, right? So you can almost see that it's like just replacing some of the weird characters with underscores. And like the space became an underscore, the colon nor the space became an underscore. And then the percent became an S and the backslash became an underscore or whatever. So it's like it made a little symbol from my thing because it doesn't have a name for. It's not like it's like X or something. It's just like a one off little string. And look at the address where the string lives, 558. That's the same address space as the main code, the executable code. Okay? And it's at 2004. It's not that far from here. It's after like it's bigger than this number, but it's not that far from this number. Any guesses on why they would like put a temporary one off string close to the machine code if you were writing a compiler. Yeah, more easily accessible. It's just a fixed offset from where I am. So the op code can be like, hey, you're going to find this thing 1,000 bytes in the future. Okay, cool. I'm just going jump 41000 bytes. That's partially because every time we run this, those addresses on the left are going to be different. The address is randomized. And we did that before, were like when we see addresses, they're different every time you run it. That's in order to keep packers away. So there's a lot of these relative offsets. Like here I am and I'm going to keep my data over here. All of this is way too detailed. I'm just throwing it at you or whatever. And I say that because again, if I do the wrong in detail at the wrong time, some of you are all in and some of you are like now I'm out. That's too much detail for me or whatever. If that's you again, snap in with me or whatever, you know. Okay. All right, when I do this, part of what I'm doing also is a little bit of, there's like a fancy education term for it. When you're like you go watch the videos like a flipped classroom thing or whatever. This is almost like deductive reasoning, where it's like, let's look at the real thing, and then you reverse engineer the properties of the real thing. Here's the real thing that we're seeing subtly under the surface of this that we're going to talk more about on Monday. But instead of like saying, here's what I'm going to show you and then to show you, we're just looking at real stuff and then seeing the patterns ourselves and emerging from it. It's an inversion. Here's the inversion I'm talking about. I have implied vaguely with hand waving, that argument to functions happen just above the function call. Can you maybe even start to make guesses of how arguments get passed to functions by reference? This stuff is setting up arguments to print F c. This stuff is setting up arguments to gets. If we were to indulge the geekia side of ourselves for a second, and now treat this like you are, I don't know, Isaac Newton figuring out how gravity works or something, and you're just like throwing apples and timing things and counting or whatever and things like that or whatever. If you just had to make some guesses of like, okay, well how exactly does the first argument get passed to that function with a register or something? Right? All right, slim experience, right? And say, all right, cool. So if we take that nugget of truth and you say, okay, cool. Like swarm of vance it or crowd sources or whatever registers or something like that. Which register where a register is loaded or how a register is loaded? Well, this is a register being loaded. This is a register being loaded. This is also a register being loaded. That's a register being loaded. That's a register being loaded. That's a register being loaded. That's a register being loaded. Okay? Which one of those registers is consistently? What we think might be the first argument to the function in code. Which register is consistently holding at the call time? The first argument to the code that you written, right? I wrote print F or whatever. What's the first argument to print F? It's that format string. So where's the address of the format string? Just at the moment of call printf. At this exact moment, which register is holding the address of the format string? Which one? No. Ra actually no. Rax is not holding that. It's a good guess. Yeah, RC. I don't see an RC. There's an RCX afterward, but that's that's some other stuff. R D what? R D X is set here and it's not set anywhere else and I don't think print F took standard in. Right. Yeah, it is. Rd R DI is the one that holds the first argument now. Is there any sensibility to that? No, not at all. It's just convention. Right. So, it's it's just like, you know, like I moved to France, I didn't speak any French, you know, So you just like start picking stuff up and you're like the most important word became. It's just that that really helped you just like absorb crap from hearing things like, okay, I'm going to just mimic what I hear. Rdi totally happens to be the one that takes the first argument, the second we can confirm that here, note the way that this RDI got loaded. It got R RX had a load effective address of the stack variable. If you take a look at this calling structure here, gets receives buffer as the first argument buffer got set to a to RAX. Then RAX got moved to RDI, which happens to be where arguments are passed. Okay, cool. That wasn't necessary. It's just saying that you as little scientists or whatever can just look at stuff and if you're vaguely in the area, you can decide, okay, I get it. Maybe there's some patterns, Make a hypothesis, test your hypothesis, whatever. Okay, great. Maybe last time when I said, here's the pseudo code and I lost some body language in the room, I'm just guessing because nobody's like, wait, you lost me here. It might be because I didn't do any of the stuff after I got to a place. And it's like, okay. But I didn't talk at all about this junk. I just ignored it. And maybe I didn't say ignore the junk at the back. I can say that real quick. This thing here from here to here is, it's a cute little thing the compiler will do, called a canary. At the top of the function, kick, kick at the top of the function, these two lines happen. And at the bottom of the function, few lines happen. Here's what those literally do. I'm just going to tell you there's going to come a day where your knowledge of the canary is going to make you feel like Superman, right? Like you're going to be like, holy crap, I am the most bad ass coder and hacker there ever has lived. There will come a day where this exact sentence that I'm saying, you're not ready for that day yet. I'm only telling you just in case you want to completion score or whatever, but soon you're going to be like, it's really important that I know that and I feel like a complete bad ass for having gotten it right. Here's what happens. This literal thing here is reading from the file system a random set of eight bytes. It's actually more like seven bytes that are random and always null bite. It's reading seven random bites at the kernel put there at the beginning of the program execution, then it's storing those random bites onto the stack right next to the teacher. It's like saying, here's all my cubbies and these last, last eight bytes are always filled with a random bit of noise, I shouldn't say always. Whenever the compiler knows that you're taking in keyboard input, it's thinking, oh little, crappy hackers are coming at me. Here's, I'm going to stop the crappy little hackers. They put eight random bites in the very last cubby. They call that a canary. It's literally like canary in a coal mine. They're going to say if somebody kills that canary and that thing, then throw an exception because bad stuff is happening. That's what that is there. It's there to protect us against hackers. We, the hackers are going to get around it anyway, but it gets in our way. It's like more work to basically make a fake canary. And put in a fake canary so the teacher doesn't realize that reveal what is dead because I definitely going to see canary, but I'll just buy another one. She doesn't know the birthmarks of her canary or cloning. Here is where it reads random bytes from the file system, puts it into the stack. Here it loads from the stack into RCx, X Ors, RCx with those same random bytes from the file system. If they're equal, it will let you leave. If not, it's going to call stack check failed. And then that will shut down everything and do no more executing, say somebody screwed with my canary. Therefore, I'm just stopping everything that you're trying to do that's a canary. Not necessarily topic or anything else like that, but just in case I lost you with like, hey, you ignored all the stuff after this. It's because my brain is like, oh, you can totally ignore all of this and you can totally in all of this, my brain is just like, I just want to see these lines. If you thought that was me cheating in some way or whatever, it's not. It's just that This is canary stuff. That's canary stuff. Okay, cool. With that, none of that came from the coder. That's totally from the compiler. I'm ignoring the compilers. Dumb stuff and just concentrating in the coder. Okay, and that's it. Yeah, here is this S, I look for that S colon, because that's like a different addressing, right? We don't see anything like that anywhere else or whatever. Like I would never write an S colon square bracket. I don't even know how that convention works, but it is some file system thing that loads into a register and writes it onto the stack and then clears that value. They're even clearing the value in case you, the hacker are able to read the register or all the set up, this micro. Then I can see the FS pick back up at the end where they do the opposite. So that was how I would know is this FS business and that's it. Okay, cool. Now, like I say, very soon, next week you will be hacking these programs. I might turn off the canaries for you, just like here, kids hack the teacher or whatever. But then we're going to turn back on the canaries. And when we turn back on the canaries, how are you going to hack it? You have to read that cubby value and make a copy. And as you go doing your evil thing, you have to put the canary carefully back where you left it. All right? That's how you're going to end up when you do that on the day that you crack a canary. I'll remind you of this moment. Say, don't you feel like a fricking superhero or like an evil villain, or super villain? Maybe you will. You be like, holy crap, I read a random value off of the thing from a colonel and I like wrote it back into place carefully or whatever. Like I can't I never would have thought I was capable of that. Okay. Yeah. It is random values that we're going to put in your local variable space. If I'm making room for you to have local variables in your Python program, A equals 12 and equals 24, I'm going to put random values very last spot. That's because if I screwed up as a developer and I allowed a user to do bad things. Here's the first example we're going to do in this class. The first hack you're going to do is called a buffer overflow. It's classic. It's like learning sorting algorithms in an algorithms class. Imagine that instead of 25, I wrote 250. Now you're not just limited to writing 25 bytes, but you can write 250 bytes. What that means is that you can edit the stack well beyond where the kindergarten teacher lives. Maybe my kindergarten teacher wasn't that good of an analogy. Local variables live between the base pointer and the stack pointer. If all those local variables are here, after the base pointer is like my return ticket home and all those other things like that. We'll talk more about that on Monday. If I'm filling this all in with noise, they put random values that are hard for me to predict right there. So that if I just do bad, in fact, let's try. It's, I'm going to take my own pseudo code, which I think is what's going on. This is not the lecture I thought I'd be giving, but I'm just trying to fill it out. I'm trying to read your body language. I hated covid teaching, right? I just a bunch of black boxes. I got no idea what here I can look at you and you're like, okay, cool. You're with me. You're not with me. You're with me. Okay. 60% with me. I got like a space shuttle heads up display over like the engine levels are here, whatever, right? Like I got a lot of information coming off of you, which is great. Thank you for being here. Words are typing, I just typing. Set, Paste. Okay, I'm going to allow myself to hack myself. All right. I'm going to say, hey, you're going to write into this buffer. And the buffer has got 25 characters, but I'm going to let you write 250 characters. All right, so I'm going to run it. The compiler is like, hey dumbass, don't do that. But it's just a warning. That's cool, I will ignore your warnings. I could just say and says you wrote and no problem. But I can do this stack smashing detected, terminated, aborted core dump. Okay, so that is basically saying this person filled up all of the kindergarten cubbies and one of them had a random value that I was going to check. That random value is no longer what I thought it was. Some fishy crap is up. Stop doing anything interesting with the CPU, because if you do, you're going to get hacked and the whole system will be taken over. Okay, that's how that feels like. That's the canary stack smashing detected. It's because there's a random value there that I overwrote. Yeah, Yes, yes, there's many ways. Yeah. And I'll show them all to you. Here's one. If I do this instead of a format string, hey dumb ass, don't do that. Hey, dumb ass, don't do that. All right. Cool. Got now I can type and it'll spit back out and no problem. Whatever I type, it's going to put that back in. But if I type percent, percent, percent, percent, that ain't percent, percent, percent, percent, those are addresses that's now reading crap off the stack back to me. That world, I'm like reading values I shouldn't read, which can include the canary. Okay? In this world I can actually do surgery to the system computer where I can write bytes anywhere I want. If I just know an address to write to which I won't know an address in this one, go right here in this one instance. But if I can figure out an address, I can write bytes to that spot or whatever, by the way. The fact that that compiler warned me three times over might make you feel like what you're learning in terms of these hacking techniques is not that applicable to real life. You're like, who's going to actually ignore all those compiler warnings? These compilers are smart or whatever. And I'm going to give you really dumb problems where I ignore all the warnings of security and I intentionally make really stupid choices as a coder. And I'm going to let you hack me. That's going to make you feel like you can only pull this crap off when somebody is being stupid. But that's what the second half of the class is for. This is you in your training ground. This is, I don't lifting weights and stuff or whatever. But then you get out and you start street fighting. And you're not punching at their face, you're punching behind their face. So you give more energy and you're like twisting your knuckle and throwing elbows or whatever. It gets harder out there in the streets. We're going to get to the place where there's no compiler warnings, there's nothing else like that. It's the latest stuff fully fortified and you're still going to pull off the hacks with the lessons you picked up in the gym early on. That's the stuff that gets pretty scary or whatever. And that's when like there's a CVE that's like a, you went to this website on Chrome and your calculator opened, You know, That's the sort of thing that should never happen and can. Okay. Yeah, so I assume 3.5 I guess. More data or whatever. So some max question, we'll spend a whole day or two on like the print format vulnerabilities and things or whatever later and things like that. But his question is like if I change it from percent to percent, what changes percent D or whatever? Here's the thing. All of our cubbies, they're just like zeros and ones, right? If there's zeros and ones, the percent D or percent X percent or percent, they're all just saying, how do you want to look at these zeros and ones because the computer is dumb. This is like, here's 0.1 If I say percent d, it's going to give me that pointer as if it were an integer. Or maybe it's a string. Maybe I wrote and rules. But I look at it with percent D. And it's going to tell me the words of the letters of Andy as if they're a big old integer. It's the print F is trying to format weird data in a way that's useful to a human, right? Like it's not made for hacking, it's made for displaying text based adventure games back in the '80s or whatever, right? Like I want to lay out my columns and you're going to fight a wizard and stuff or whatever, trying to make like Askar. All right, fine. It's really just saying the character behind the percent. It's more for us. I'll show you some other tricks in there. I could say percent I actually got a Seg fault which is cool. Percent D, I got 26, 60. By the way, Seg faults, they mean something very specific that you're going to get good at in this class. Also, I'm like peeking ahead. I got a goal today, I shouldn't be peeking ahead. A seal happens every time you ask the computer to look at an address. The address isn't a valid address. It's because the address supposed to be inside of segments, if you like, read inside of this segment, it's going to tell you what's there at those zeros and ones. You can even see here, if I asked it for percent, it said seg fold. If I asked it for percent D, it didn't crash. It said the number you're looking at is 2,660 Okay? Whatever bits I was trying to read, they have the value of 2,660 as a decimal, as an address that's not a valid address, as a percent, it's trying to read that address and then go see, is there a string at that address? No, there's not. In fact, that address doesn't exist. I give up. You're crazy. Why are you asking for an address called 26, 60, Okay? So every time you see a sec fold, it's because an address is being evaluated and it's not in a valid like address space. And you're going to see a lot of Segal, you're going to make a lot of Sycoright. Yes. Not inside of my Docker image. So if you are one of the people who has got a call, you can actually run a magical command that will tell you what address it tried to read, that it failed to read. And a lot of times that's helpful if I'm spamming keyboard spam into my copies and it's trying to read an address. So for instance, like if Yeah, we're going down the rabbit hole and again. Yeah. Okay. All right, let's get back to the simple stuff or whatever. We've got our pseudo code. This is our pseudo code so far for revenge one, revenge two. Let's get back to our main story line. Get revenge. Three, CH mod P X revenge. All right. Two minus D revenge. I just like the fact that reverse engineering sounds like revenge. I don't just build it into the brand somehow served cold all that, Okay, Now we've got some other crap going on, okay? All right. Now we've got maybe some work to do it now. This feels foreign to you and that's why we're doing it. Here's what we recognize. What do we not recognize? All right, the earlier question, what can, no, I can ignore all this stuff above that S story line. All right, great. Now we're starting to see this thing almost in like little micro chapters, right? So here's like the set of instructions that was doing the F gets. Okay, cool. We're cool with that. We've done that one twice now. Okay? But there's something new after the F gets string length, okay? So if I see string length after I just received input from the keyboard, I'm going to think it's checking how long my string is saying. All right, so what? Yeah, we're definitely going to be doing a four loop. We're definitely going to be doing a four loop. So this is about how does a four loop actually feel in code? Because it's going to look a lot more complex in assembly than it is in my pseudocode, right? And the goal is to not let all that complexity get in the way of my life, right? I'm like, okay, yeah, it looks complex but it's not. It's a dumb, it's all dumb. Okay. So let's spend just a second here. We did do the F gets. One thing has changed about the F gets, and that is the address where my buffer lives. What has changed before it was 48 bytes to the left of the base pointer. Now it's even further, it's like saying due to like budgetary reasons, we're going to just have more kids in the classroom or whatever. And now you sit in the back or even more rows away from the teacher. All right. So what's five times 16? 80. All right. So instead of being 48 bytes away from the teacher, we're now 80 bytes away from the teacher. All right, and that's where our buffer lives. Okay, no big deal. But just remember var 50 is like where our buffer. I bet there's a command where I can replace all the instances of var 50 H with the word buffer. And it'll just like say buffer everywhere, But we're just going to use our memories. Now, how does string length work? String length is going to receive an address where string lives. It sh, write something out from that. Here's this weird little line. This line doesn't make any sense to me. It is writing zero into var 58. Okay? That line is like a whole story unto itself. But if you have to guess based on that one line and your knowledge of everything in this class so far, what is that line doing? It's initializing some variable to zero. Probably I, Right? If we think there's a four loop, come in and there's a string length that's I equal zero, all right, fine. All right, then we run string length on the buffer. What is the return value from string length stored in? Where do we put our return values? That's the type register, A. That's right. The return values are always in the A register. Look right after a string length. It went and it did a whole adventure in Kansas City and it flew back home. This is, the refrigerator magnet is right there. All right, so that's like the picture of what happened in Kansas City. That a register gets stored onto the stack just before the buffer. What do we got? Let equal O n equals string length of your buffer. Something like that. I'm going to like put that in my pseudo code just so you can see it. So we have like this guy, we have gets and probably like int I equals zero t n equals string length of buffer. That's what I think has happened so far to get that point. Okay, that's 40% nodding, maybe 55% nodding. I'm okay with that. All right. Okay. Here we go. Then what does it do? It puts that into the A register and then we got some wacky stuff going on here. Okay. These two lines are like, why Skynet isn't a reality yet, right? Like these two lines are so silly. Here's the return value from string length, it copies it to 54 H, a local variable. Here's the next line. It reads the local variable 54 H and puts it into the register so that it can do math with it. Dummies, It was there the whole time anyway. All right. It's just saying because the compiler is literally just taking your code and it's like here's a machine code that'll do what you want. Here's a machine code that will do what you want. Each of those, it's because it's like just two chapters of the book put together. And it's almost like a previously on this show, we did this thing or whatever, right? So it's just like loading it back into memory because that's how the compiler works. Like you wrote these symbols, I replaced them with this code. You wrote these symbols or replace them. This code doesn't have contextual awareness, right? That's why like GPT will forget your stuff after 4,000 bytes or whatever or whatever. Like there's working memory and that's where we are humans. And so anyway, so those two lines are like proof that the computers are dumb. Okay, That's okay. We know it's all dumb. All right. So I think today I'm saying details that I probably don't need to say. And that might be sending you the wrong emotional message, all right? So pretend like I did the opposite. Pretend like I am just going to say, hey, what do you think is happening inside of this thing? All right? It's a little wacky. I think there's two addresses involved here. So let's take a look. A is getting the value, right? Like a register is getting the length of my string. This thing here is looking for an address. What address is this going to? R BP -48 plus n. Okay? What is that? That is actually how we access stuff in an array. All right, I'm going to show that to you in pseudocode, and we'll go back back and forth real quick in Pseudocode. Here's what's actually happening there. I have buffer one, buffer two, and then I'm reading into buffer one. I'm getting a length of buffer one. Then I'm saying buffer two, N equals the null byte or zero. Really? I'll just say this thing, is this line of code a little bit wacky. But I'll move that. This is buffer two square bracket n. Now think about that for a minute. How does an array work? An array is just an address. I say, hey, I want to go 20 bytes deep into your array. I want to go to the 20th character of this string and do something there. I'm going to take the address plus 20. That's it. This is instantaneous access to the element of some other buffer which lives at RBP -30 instead of RBP -50 maybe. All right, cool. Okay, then we're going to set to zero. Yet Again, compilers are dumb, Fine, actually this one is probably my fault. This is going to set to zero. All right, here's how I intuitively look at a loop. Here's how you can intuitively look at four loop. The very first thing that happens, just think about this from your knowledge of code code, how does a four loop look? You say equals zero, less than n. I plus plus, and then do stuff here. All right, this line, everything before that first semicolon gets executed before the loop even begins. And only once then it checks to see is this condition true? If not, it will do all this stuff, then at the end it will execute this. That's how four loops go in practice. Everybody's comfortable, four loops, maybe A in particular. I hate to do this right there, you guy with a hoodie. I have not felt like I've connected with you. I don't know if you're having a bad day or whatever or something like that, but I keep looking to see if I can reach you and I can't. Is there a reason why you're just okay? Are you okay? Okay. All right. So your body language is like throw. I'm like, man, I can't get that guy. I want to just can't. I feel like Michelle Pfeiffer and dangerous minds and it's like, I know you killed a man, but like I can recover your soul anyway. Sorry, It's just my own neurosis. All right, here we got I equals zero, less than N plus plus. All right, let's look for that. I keep going over to the other, there's the I equals zero. All right? And then what's the very first thing it does? It jumps to the end of the loop. All right, you can follow this little arrow. Radar two is pretty slick that way. It gives you a little arrow and saying, here's where you jump. Okay, cool, I jumped. What does that do? It puts into the A register. And then it compares a to the other variable, which was n. That is literally, then if it's less, then it jumps back up here. That is, if I is less than n, then do stuff and then it jumps back in. All right, this is how four loop looks in code. I'm going to do my initial part. I'm going to jump to the end. I'm going to do a comparison. If the comparison passes, then I will do the actual code you asked me to do. Now I'm going to ignore all of that for just a minute. Then go to the very end of the four loop. That is I plus plus, that's add one to I and then do the comparison again, and jump to the back. All the guts of a for loop, no matter what's going on inside the for loop are here. Here, this stuff in the middle. This is the part that is the coders intention inside a bit, All right? But when it comes to us learning how to fuzz our vision and what can I ignore? What can I ignore? When I see that arrow arrow pattern, I'm like, oh, it's a for loop. If I think it might be a for loop, it's this line that validates it for me. If I see that line add one, I usually use that line to let me know which variable is the index is the right. If I see that, I'm like, oh shit, that's an I plus plus I'm on this now, all of a sudden, in my mind, bar 58 H, I've just replaced it all in my head with. Right. We guessed that earlier, but that's the one that confirms it for Yes. Yes. It would be similar with while. But you know what should do. We should just make a while loop, compile it, and look at what the while lop looks like. Because it'll do the same thing. It just won't have the initial and it won't have the plus, plus at the end. It'll just jump to the back check and then jump back to the beginning and do okay. Now, getting to the guts of ith. I've got 2 minutes left, 2 minutes left. That's the other thing I get from body language. Don't actually have to look at the Cloc. I can just look at like when you zip okay. Some percentage of class just zipped. Okay. Check the clock. All right. I love it. Screw zoom. Okay. Sorry, there's three people on. This is now N. Now let's look at this. N is in the A register and it subtracts from N. All right? Subtracts from N. All right. I'm going to write that down. There's like a N minus somewhere. I don't know where or whatever. It's like, it's almost like a temp variable or something. Is N minus. Temp obviously doesn't exist but like it's in a register N minus I. I just want to like remember that. All right. N minus I. Then it takes N minus minus one. All right? N minus minus one. That's now like the register here is N minus I minus one. Okay. And then it loads up again. All right. Fine. This one I don't know what that does. Something I don't know but it's not relevant. It wasn't on my list of things that you had to know, so you don't have to know it. All right. So I ignore it. It's not on my list. Fine. You can go look it up or whatever. But it's just going to distract us. Even like the moves that have different things at the end, I don't really even care about those. I'm just going to look at them as moves. All right. Rbp plus R A X, which is currently set. Literally two N minus I minus one. No, no, it's set to -50 This is buffer one square bracket is getting moved to the D register. It's basically saying like temp two equals buffer one. All right. Some temp is N minus minus one. Temp two is this. Load that into A and then save that byte into buffer two. Oh, I know what's going on. Buffer two. N minus minus one equals buffer one. That's the line of code here. Okay, that took a little bit of work to get at. Intuitively, what am I doing? Reversing my string. All right, let's see. Wich one, they print, are they going to print the reverse string or the original string? Probably the reverse string because it's more interesting you wrote and then there's buffer two and I can ignore the rest. All right, let's run it. I should have run this from the beginning and we would have just known that was this revenge three. If I write Andy, it's going to say you wrote. All right. That's all it did. It just reverse the string by copping into a different buffer, in a flipper order, whatever, things like that. All right. Much ado about nothing. Cool.
Recognizing common code patterns in x86
From Andrew Novocin February 16, 2024
52 plays
52
0 comments
0
You unliked the media.
Zoom Recording ID: 4159319948
UUID: G21OtgNYQLyjDCopUliVLg==
Meeting Time: 2024-02-16 03:14:16pmGMT
…Read more
Less…
- Tags
- Department Name
- ECE
- Department Division
- Date Established
- February 16, 2024
- Appears In
Link to Media Page
Loading
Add a comment