at was like skinks on Cold ones. Okay. Yeah. Yeah, so I just used them as my I I had them and I didn't have any of the Sorus knights. I was like these guys are my knights. These are my sorus knights. They're just very they're just very effective They just have everybody thinks they're sorus. They've tricked everyone. All right. Anyways Um We talked a little bit about this last question I have but it but I'm curious to know your your actual, you know Sort of go-to strat How do you protect your tiny but powerful utility heroes? You know, we've talked about the skink pre showing up in the list We've talked about the skink stars here, right? Like these guys are huge force multipliers in the army But in the end they are not Uh You know, they're not tough like let's be honest if they can get targeted by heat they can die So how do you what's your general plan for protecting them? You have to Think about which ones you're okay to lose so Skink priest is usually one very important one nicely. He's the smallest model So a lot of the time he's behind my realm shaper engine. So unless I'm playing sentinels or Well, unless I'm playing sentinels then he's gonna be okay Um, a lot of the other ones too, like I said before when you they're in the garrison people will often Think that they can kill something and they can't because it has Plus or minus two to hit plus one save all at defense for plus two to save six upwards save from the ashlet with bear So sometimes I will put certain things into the realm shaper Just don't having an idea that if I lose them like the star seer, he's not integral to the list He gives me the minus one plus one save He gives me the hand of glory, um, you know, if he dies he it's not game over where Even if the skink dies, it's not game over But I would much rather lose the star seer or doralia I put doralia lot in the realm shaper and she got popped off once turn one which was like, okay That sucks, but you know, I way rather have my skink priest or my ashlet with bear or something, you know Sure, or what popped her off? What did it? Uh, that would have been what was it game three? Fuck, I can't I can't remember. I think it'll probably it'll probably come back Yeah, some type of shooting for sure. Um, but again, that's like something that he's oh it would no post nicks post nicks Okay, yeah, so I was playing I was playing and and I was in range Uh, he was one drop. So I was like I put her in there I'm like if you waste your 15 shots in your face to shoot him. That's a whole cp You're not doing anything else. You know what I mean? You can't get really really get out of their threat range Anyway, it's 32. So yeah more with the the iron scale Exactly for the shooting I I or sorry for the hero face shot I could have but then I was like and also cpy So, you know doc doesn't get the most cp. So, um, yeah, so but otherwise. Yeah, keeping things safe It's just yeah either behind the temple in the temple to garrison or source guard obviously with the slant Um or terrain just you know using terrain. I love I love places that like I'm so used to I'm a bit of a terrain snob. I guess you could say Just because jordan has such beautiful terrain and we play on like such beautiful boards that That will one thing a funny thing about the boy is actually the table that won best terrain Uh, it was table one And it was all of the printable scenery elven table. You probably recognized how it from watching the Yeah, if you know what I mean So it was like all nicely painted green like same as jordan's that he has and then it actually had the season of war Objective markers the ones that like jordan made on his store So I was it was funny because the guy who came up and asked he was like, oh What do you think like I made this table? I was like, oh, this is great Like we I play we play on a very similar like all the time and he's like, yeah these uh the objective markers were are awesome like Like not knowing that jordan is standing right there and he's the one that he bought them from So jordan's just like yeah, like those I made those and he was just oh, what do you mean? And he's like, yeah, I made those and then I look at him like they're actually nicer than the ones we use Because the ones we use are like the shoddy like ones that he didn't sell or whatever on his store. Sure Just so so funny but yeah, it was uh Terrain is is always a thing, you know people always talk about tournaments. It's always so nice to have Like nice terrain at tournaments 100% cannot cannot agree more Yeah, cool. Oh, I've got a few. Yeah hit me. I know we're coming. I know we're kind of on time So real quickly What are they called bound in the spells? Yeah, that's it. What are your thoughts on on those rich? Yeah, they've changed a bunch now So there's a couple cheeky ones that I've thought of Purple Sun because I think it now it it goes wild. So you can just buy that one with this land So I thought about that. I think it's pretty good, man Again, I played that last week and it did a lot of work to my stormcast. Yeah for mortals, right? It's it's one of those ones. He kept popping off that six for the d6 Oh, wow. Yeah, if you can if you can roll that then it's going to do real work Yeah But other than that bound it's like usually wizards are going to be within 30 of their spell. So It's not the biggest thing when it came out. I was kind of excited just because bound on the spells were broken before So I was I was excited that they actually fixed it properly because even with Croak bale and hopping 40 skanks all these things bound geminids was the as you guys know There's the dumbest thing ever like how that was a thing for so long is just wild and how effective it was being able to double tap and blah, blah Um, so yeah, I was a little excited to see kind of what they did with it But overall not crazy crazy powerful But I don't know what are your go-to endless spells in a surf on this or do you have I saw cogs You know, but are there yeah, particularly in the spells that you think will find their way commonly into a competitive list I think just the the ones that are already good. So, you know What's it called or emerald life storm? I've seen one of the guys who was running that I could maybe see that with 30 skinks or with the the sallies could be interesting You would need to roll a three to get a sally back, but still interesting Burning head 20 points. It's just you know a source to and it's interesting because This force actualist bear does give six inches to cast So he's one of the only models in the game other than like what archon and some other ones that actually extend the range of endless spells So, um, you know, a lot of them are a little more viable I've used shackles before but just so many models Well, not even so many shackles. I think is still really good because giants a lot of things that don't aren't have Don't have pluses to cast because they're on a seven, right? So You're often able to get them off. So I think that'd be they're pretty good as well but Yeah, like other ones that are good in other armies. I think just having the range increase Okay, we haven't talked much about croak. So How competitively viable do you think croak is right now? Like is it just that there's too much shooting and that if you get through the five star scarred, you know There's too much risk or too much shooting can burn down five stars guard too quickly Yeah, croak has a soft spot in my heart because of how good he was before but he also has a very bad spot because last year at grand clash I brought him to grand clash and I had five just five source guard with him Game one against ko and this was before you didn't have your realm shaper.  I didn't have my realm shaper. So I had to deploy and Um I was able to keep croak in cover. This was before aos 3 so it was like different rules and whatnot But he had his 3d6 mechanic. So I got the iron cloud came in the warp landing vortex 20 thunders popped out Everything fully shot into him. So he's minus one to hit plus one save You know, I mathematically he should have survived through everything but it all came down to Him doing nine wounds to croak at the very end of the day And this was game one of a six tournament where I had a ridiculously competitive army because it was aos 2 still and I rolled the 11 And and he went down turn one and I I ended up winning the next five went five one I ended up winning the next five games because like again aos 2 serif on was just insanely strong But just that that long story is just to summarize Competitively anything that you have a risk is You want to minimize if you're if you want to win, you know, a lot of games That's that's why I feel like sorry man That 10 star escarge in my mind like if I'm going to run croak, I'm running 10 star escarge 100% in my mind Yes, I'd be really curious to see you do that on a bat Let's see how that goes like yeah build build a list around that where you're doing the 10 Doing him and you know, maybe you're not you're moving up the board not just keeping him in the back You're pushing out that power projection that threat range of him middle of the table And that should still give you quite a bit else that you can do in the list I think I think it could be I have I'm just a little Find it strange. We haven't seen that. I haven't seen that as much and at least the 10 and croak Yeah, it's so so that'd be six So 6 6 6 60 they're 115 each for each guard. So two 30 plus four 30 Yeah, so 6 60 for the 10 guard and him Yeah, there's still a lot of room for other stuff in there for sure You're gonna want the ash with bear because he needs to have that for the six inch 16 So, you know a little on the expensive side still but no, it could definitely still be interesting But I I'm with you on that one like 10 guard for sure because now he doesn't get he can't garrison the temple He can't get look absurd. He can't right all these aos three rules that make the slam unbelievably good He he doesn't benefit from anymore I mean, I think Tyler the real answer is just the randomness of his survivability Right. Yeah the risk because it's all up to a dice roll and like the I think that in the end if you look at sort of spikes psychographic profile, right of like and and spike is sort of your Definer of the tournament list, right? Yeah spike hates random risk that he can't control for And the fact that you know, there is a set of dice he could roll when he takes three wounds That makes that frog explode No matter how minimal right because it is a super minimal chance to happen like let's be honest, right But because it's you can't control for it really in any way He can just take splash damage and then accidentally implode It I think that alone makes him the tough proposition spike hates spike hates skaven Which is no one no one should ever hate skaven. So I'm not with him on that Yeah Oh, sure. Yeah, no just moving on from that The skill level where where is this army ridge from a skill level standpoint? That is Oh, how much does it really require? A you know, pretty good level of skill to get good results How much it isn't more like suns where it's pretty straightforward kind of wears it on the spectrum in your mind Yeah, and I think you're asking you're Tyler both floor and ceiling Yeah, yeah, it's both irrelevant Yeah, yeah, I think it's it's it's not fully like luminous to where like It's a very very high skill cap or legion of the first prince I guess some of the other ones that you know, really good generals will take it to another level But you know with fangs and the starboard ones I think that there may be a little bit higher because you can do a lot and there's so many things to think about You're always thinking about okay, where is this unit going to teleport? Okay, where do I bring these down? It's one of those armies that you can get bogged down So I think it's a little bit higher skill cap in the way that you need to be thinking of a lot of things There are a lot of different buffs. There's a lot of different Dropping down your skinks or things so that next turn you're holding within 12 So you can give plus one to save you know, I mean a lot of aura buffs So actually then yeah, I think it is a little bit higher of a skill cap for for things like that um Maybe not as much the the staggies in the the beasts obviously they're a little bit more you can you can play them But even there there's yeah, but even there there's still a lot of you know tactical If you do with them in buffs and stuff like that But there is a lot of other just a lot of things to it So there's a lot to know so it's it's an army for sure that you get a lot better with playing Like you get better with reps and I've noticed that massively just myself and Jordan probably taught me the same thing like You know as you play them more and more you become so much so much better and You remember all those little bubble things and all those I better not pile in here because then I won't be I'll be outside of my star Priest buff Like those are and those can lose you games when your skinks don't have sixes to wound do an additional mortal Your your output is nowhere Yeah, to me. I've always perceived them as a again taking the lists on average There's variants and lists here of course, but so we're just gonna kind of average across the army And I you know my perception of it's always been it's a medium to high skill floor To really effectively pilot But a decently high skill cap As well. I I agree with you that it's like it's almost like if you took if lumeneth is this Right, then seraphon are like that Yeah, it'd be the same distance of the the bar like in prices, right, but it would just be scooted down some Mm-hmm Yeah, in in aos 2 I think it was way more forgiving Like yeah, just because you could run 40 skinks 40 skinks 40 skinks So that's where it was like people that have never even played. I remember watching so many tts games Where it's like so many people were just playing it because it was super strong Or they needed a ringer player or someone had to come in and play it and it was like They would still do well or they would still win and it was like so frustrating for people because it was like Oh, anyone could play seraphon in and we could do this and it was like Yeah, because it's just all skinks and they're still effective, but right one of those things that yeah If you it's just so many rules and and it's yeah one of those time things that Yeah, need to play games get reps in Uh, yeah, generally reminds me a little bit of donner's cane You know got some experience of course we talked about on the show that donner's came outside of marathi can be Unforgiving to mistakes, you know, it's a lot of his positioning screening I think my experience of it. It's an army of screens and hammers Gotta keep those hammers safe and seraphon reminds me a lot of daughters of cane that it seems relatively like it can be unforgiving You know, you're not Stormcast or ability or some of these other armies. You don't you don't have that So if you make mistakes, you could definitely get punished. Is that I I couldn't agree more Honestly, that is better than anything that we've said so far and and there are been games where I have made The small mistakes where things have happened and if you want the best way to kill seraphon I'll tell you right now everyone is yeah, you kill the hammers You can kill those hammers. That's You know, you can only summon 10 skinks. You can't summon you can summon ace alemander, but Yeah, you couldn't have said that better for sure. That's keeping the hammer safe is is always the number one thing on my mind Well, yeah, your bad reps have been amazing I really have enjoyed watching you play them on the channel because it's one of the best representations Caleb also with his you mentioned Caleb Hastings also really good Yeah, it's gonna give people a better sense of what all you can do with the army But yeah, watching you I mean, it's clear that there's a lot involved. It's not a You know, not an easy button army. It doesn't know me as that but yeah, it's got a lot of potency if it ran well I appreciate that man And honestly, I've had a few comments from people that have like almost maybe like tear up because it was like So nice of comments like hey rich Thanks a lot like for taking time to go through things like you're the reason that I placed seraphon And I've painted this many points and now I'm going to tournaments and stuff and it's like Yeah, that obviously there's nothing better than to hear like stories like that. So yeah, I think thanks man. Appreciate it Awesome. Well, very good. By the way, shout out to Caleb waltz who just joined us here one of your one of your opponents there What's up Caleb? How you doing buddy? I saw you crushed our mutual friend Paul round one. Well done Caleb. Well done At any rate, uh rich, thank you so much for being on show man and talking to us about seraphon. This is fantastic, brother Yeah, absolutely. Thank you so much. It's uh been watching for a long time. So super cool to be on And now that I know you're also a scaven player deep in your heart Uh, we're like, you know, like you're more than welcome back We're gonna have you back on and so when maybe maybe it'll be to come back on and talk about rats Talk about how we dig out of this 30% win rate hole that the rats find themselves in Make sure that's a tom show I I yeah, it's Tyler I might have to foist it on you just because it would be much funnier to have you in there I played rats this last weekend. It didn't go well. I'll say it that much. That's so Many of my vermin lords proceeded to let me down multiple times and then get killed by murked by zombies and I was like, oh god, why Anyways, uh, so thank you rich great show Really appreciated all your insights everything you shared buddy And congratulations again on the win very well earned. Yeah, awesome. Thanks so much Don't forget the channel season war is going to be linked Down below everything that was mentioned in pick of the week linked down below Don't forget to hit like subscribe. Press all those buttons. It's important to press buttons That's how that's how the other people find the show. It really helps us out It's so easy. It takes not but a second of your time to just click a little button And it's so nice. It makes us feel so happy. So thank you very much everybody for watching. Tyler. Thank you as always Ridge thank you one last time all of you out there As always, we'll see you next wednesday


At Audiology Associates of Prestonsburg, you can live your life the way you want and find the freedom of better hearing. You'll experience patient care that is specific to you with exceptional follow-up care that ensures your hearing and balance needs are being met. Audiology Associates at 1428 Northlake Drive in Prestonsburg. The Floyd County Library will be hosting two meetings this week to speak to those with special needs and to learn how to better expand their services and programming. We'll be having a special needs family community meeting at 12 o'clock. That is so that we at the library can start planning programs and doing events centered around special needs families. That includes a whole spectrum of an audience. And we want to try to get those families in and say, hey, the library is yours too. You know, we want to create library users with them. If you or someone in your care has learning or intellectual disabilities, is hearing impaired, blind or physically disabled, gifted and talented, or needs other accommodations, this meeting is for you. There was a lady moved in here just here recently and she had two kids that were special needs. She said in her community in Atlanta they had programs monthly and weekly for those two kids. And I asked her, I said, how can we do the same thing? Because, you know, if she's got kids, that means they're, you know, all across our community, there's kids and adults that need this kind of service. And we just, we want to include everybody. The library will be hosting a meeting Tuesday, January 31st from 12 to 2 p.m. and Thursday, February 2nd from 5 to 7 30 p.m. Reporting for Mountaintop News, I'm Brianna Robinson.


Imo Stade Gwbner hwpwysodim ma has expressed shock over the killing of the APC stalwart Ahmed Gulag, describing the incident as unfortunate clear, an unfortunate clear case of political assassination. Addressing emo people in a broadcast at the Government House in a weary emo state capital, the governor said he is really saddened by the gruesome murder which underscores the ugly security situation in emo state interests in times. Imo Stade Gwbner hwpwysodim ma has stated that the events of the last few weeks do not represent the true character of emo people and assured the people that the government will not leave any stone unturned in going after anyone or group perpetrating criminal activities in the state. He is supposed to travel incognitive according to his friend that was with him during the incident. Someone must have trawed him from his hotel to the airport. That is exactly why this gruesome murder appears to be a clear case of political assassination. According to the reports by the police, it was shot in cold blood and the assaultants did not remove a pen from him. Cymru fydd ydych chi'n edrych o'r teimlo y galler fy o cheat? Roedd hyn i chi'n ystod o'r rhanio a'r rhanio i gyllideb yn gŷn. Felly, nes ddwy'n ddymayo, mae bydd yn fawr i siano am ffoblau fe ymryd a hmu'r bywyr gŷnol. Rydym yn un modau'r wahanol ac mae'r ddebyd. Nawr mae'r fath am eu godi, ysgaf i'r hyn yn maen i'r defnyddiadau.


Oh, so cool. Man, Twitch, feeling like old. Just want to make sure this is working. Cool, all right. We will see how this works. All right, cool. Hey, everyone. All right, let's pick up where we left off. So we left off writing this program. So we had a very simple text program. So we're writing a very simple echo program. As we said, the purpose of the program was to read in up to 100 bytes from standard input and output that to standard out. All right, so I know you all finished your homework. So who wants to help me finish that? So why did we first subtract 100 bytes from the stack pointer? You said it was because we would be able to use that 100 bytes and nobody else knew it was there. Yeah, perfect. Thank you. Hopefully I said the right things, but who knows? OK, cool. So we first subtract 1,000 bytes. Now we want to call read. We want to call the read system call, pass it 0 for the file descriptor, because we want to output to standard. We want to read from standard input. We want to pass in the RSP as the second argument. That'll be the memory location of the stack, so we can write our 100 bytes there, and then we pass in 100 as the last option. So what do I want to do? What's my goal? How do I actually make this system call? What's the high level goal that we want to do? We need to do a read, so you want to put rax, well, 0 into rax. OK, 0 into rax. Cool, what else? We need to fill in the other registers that get used for the system call, which include RDI, RSI, and RDX. So RDI is the first one. Is that right? Yeah. So 0 into RDI. And what was the next one you said? What do we want? RSI? SI, yeah. And then what do we want to be inside there? I did RSP, but I feel like that's not entirely right. That is entirely right. Trust your gut. It is correct. Cool, we'll talk about Y in a second. And what's the third parameter? Our number of bytes, so 100 needs to go into RDX. RDX, so 100 into RDX. So we can see how we translated basically this high level of what we want to have happen. We want to invoke this system call. We want to pass in the parameters 0, RSP, 100. We use this nice link that Zion just put into the chat. We then add, we see that the system call for read is 0 into RIX. And great, so then we can translate that from this high level, hey, we want to call the system call read and pass in these values to the more mechanical, what do we actually want to do in assembly language? All right, so we want to move. So what's the instruction? So pretend you're, I'm just fingers here. What do I type in? Move RIX comma 0. Moving 0 into RIX. Next one, move RDI comma 0. What about this one? Anything special? Move RSI, RSP. Yep, so move whatever is inside the stack pointer. Do we know what value is going to be inside the stack pointer? No, because it's standard input. We're waiting for somebody to type something. Not quite, right? We know something about the stack pointer, RSP. There's 100 bytes waiting for us? It was whatever it was before main was called. It's now 100 less. That's what we know. So we don't know anything else, but we know that. OK, cool. And then we want to move into RDX 100. Sweet. OK, so this will then read in 100 bytes into wherever the stack pointer is pointing to. And it will fill that up up to 100. And then now we want to call write. So we do the same things. We'll look up in this fancy table, write as RAX 1. So we can then use the same logic. So we want to move 1 into RAX. We want to move into RDI. We want to write out, why are we writing out to file descriptor 1? What was file descriptor 1? Standard out. Standard out, yeah.  And oh, I'm missing something here. How do I actually get to the system call? No, you need to execute this call instruction. Yep, yeah, syscall, beautiful. Cool. So these should, and I'm going to get rid of these comments now, right? These comments were helpful when we were kind of outlining what we needed to do. But honestly, as long as somebody understands assembly, they should be able to understand this instruction here. So I'm going to get rid of those. All right, let's try compiling this. So I can never remember. Every control sequence to make the font bigger is always different. Let's go hacking.  OK, so this is echo meeting. So I'm going to compile this, gcc echo underscore meeting dash s. It compiled just fine. I can check the exit code. The echo code was 0. I can see that a.out the last time it was compiled was September 29, which happens to be a week ago when we were last looking at this. So now I have a new a.out so I can run it. What's it doing? Why is it just hanging? Did we make an error? Are we stuck in an infinite loop? It's waiting for you to type things. It's waiting for us to type things. It's reading from what? Standard input. That's us. It's waiting to read from standard input. Beautiful. So I can type in foobar hit Enter.  So first, before we dig into what's happening, let's look at what's going on. We can use S-trace to make sure we're doing the right system calls. OK, so I can do that again. And now this is kind of cool. We can actually see why it's hanging. So it has all this other stuff and all this other junk that we won't focus on now. But we can see that it's calling read. And it calls read. So it read in 0, ended up being foobar end 100, returned 7, and then we called write 1. So this is correct, the file descriptor. And it's not, I guess, because it's too many characters. It's not showing us the comma 100 there for the 100 bytes that we're writing out. So why am I getting all this additional junk? Where's that coming from? There's a bunch of data on the stack and the string input isn't null terminated necessarily. So it's just printing out all the other garbage on the stack. Yeah, let's do, I realized last time we didn't do an actual stack example. So let's quickly run through an example of the stack. First off, and this is something that Jan is 1,000% incorrect at and I am right. And so, especially this is your first time learning this, you're learning this from me, you'll never do it wrong in the future, you'll always do it correctly. So we saw that we subtracted 100 values from the stack. So we conceptualize and think of the stack as something that starts at high memory and grows down. And so we visualize that with drawing just kind of like a box with high memory at top and low memory at bottom. Now you may say, Adam, how do you know that you're right and Jan's wrong? Well, A, because he draws it left to right, or which he does bottom up, which is insane, which is even worse than left to right stack growth or right to left. That's just absolutely horrible. And the way I know he's wrong is in the Intel manual, it's specified like this. So it draws out memory and the stack from high to low memory with the stack growing down. And the, so the notion of a stack is essentially, when you get into data structures, you're gonna study all kinds of interesting data structures. And one of these data structures, and all this is, is you can think of like a data structure to have different operations. So a stack has fundamentally two operations.  So if I were to put, let's say, you can think of it like, oh, I don't know, I wish I had it here. At home I have an arrow press that has a very, very good demonstration of this. But essentially, you can think of if we're putting things onto the stack, then, and if we put, let's say, first Zion onto the stack, he gets pushed onto the stack and then Will gets pushed on there and then Adam gets pushed on. When we pop something off the stack, Adam will go first and then the next thing we pop off the stack will be Zion and Will, and then after that would be Zion. So the way we think about this is, and this is kind of the important concept to think about when you think about this at the assembly level, at the high level, data structures, thinking about a stack in terms of push and pop is all you kind of really need because you have this nice interface to use it of just doing push and pops. Here, we're simulating that with a memory region that we say, okay, anything that is above, so anything at that memory location, which is at the current point of our stack and above, is memory that is used, it's in the stack and anything below that is garbage. So let's say that the stack points to memory address 10,000 in hex. This is essentially arbitrary at this point. We don't actually care. But once we know that, we know that, okay, anything above memory address 1,000 from literally, and I don't know how many gigabytes that is, it's definitely a lot. Somebody could calculate that, that'd be interesting. But basically, the way this stack is currently constructed, everything from, all those Fs, all the way to 10,000 hex, all of that is currently being quote used by the stack and this points to the head of the stack. So this means whatever is right at there in memory is what's going to be, is what the next thing is that will push and or pop off the stack. But this also means that anything that's below the stack, so below the stack pointer, so at a negative offset is garbage and we don't care what it is. It could literally be any values, but it doesn't matter. Cool, okay. So we'll just walk through this example of two instructions. So different programming languages have different, or sorry, different assembly languages have different ways to interact with the stack. And so in this example, X86 has instructions to push things onto the stack and pop things with the push and pop instruction. Otherwise you would move something into where RSP points to, that would move something onto the stack and then you'd have to decrement the stack operation. Push and pop actually does both of these simultaneously. Now, what are the values in my registers? So the value inside the REX register we'll say for these purposes is 100, or sorry, 10. So it's hex A, RBX, no idea, we'll say zero. Now, what is the value of RSP? Kind of a similar question that I asked when I were looking at the other code. So what's the value here inside RSP? What does it have to be? It's a hex 10,000. It's hex 10,000, why is it hex 10,000? Because in the drawing that you put, that's where the stack pointer is, that is the head of the stack. So that's where the most recently pushed value onto the stack is. Beautiful, exactly. And this is an important point. These are inextricably linked. The only reason why I'm pointing this stack at memory location 10,000 hex is because there's the value 10,000 hex into RSP. If I were to change that value, now my program or whatever, like as we said, when I subtract 100 bytes, that moves the stack pointer down 100 bytes. And now to our program, everything above there, those 100 bytes are in use, we're using them. And anything after that is garbage, cool. So it's important to keep in mind that the arrow here is just an illusion. The only thing that matters is that the bytes inside of RSP are 10,000 hex, cool. All right, so now we're gonna walk through step-by-step doing these instructions. Can I ask something really quick? Yes, you definitely can, please. One thing I kind of wondered behind the scenes is how does push and how do push and pop know how much to increment or decrement? Because I mean, when you're allocating space on the stack, you usually add a subtract, I actually kind of forgot for a second. When you allocate, you're subtracting because you're going down. Yeah, so how do you? So yeah, that's size, that's a great question. So at least a half to, so I know in this case right here, the assembler, I would assume, and actually let me look this up, let me look it up. I'm fairly certain that, let's push it, I think. So I believe it has to do with the, if you're using 32-bit or 64-bit instructions. So a push instruction in 64-bit, which is what we're looking at here, will always push, you can think of it as the size of a register. So how many bytes is a register in 64-bit? 64.  Yep, perfect. So eight bytes, right? So it's going to push eight bytes, so it's gonna take whatever's in RAX, take all of those eight bytes, copy it onto the stack where it currently points to. So those memory locations, 10,000 is overwritten, 10,001, 10,002, 10,003, 10,004, 10,005, 10,006, 10,007, and 10,007, because that would be eight total, and then it's gonna subtract eight from there. On 32-bit instruction sets, it only does four bytes because the registers are only 32 bits or four bytes wide. So it's always a constant value. It's a constant value based on your instruction set. Okay, so it's always gonna be for 32-bit, it's always gonna be 32-bit, push or pop. Correct, I don't know if it's possible even to write. Zion, do you know is it possible to write assembly that pushes only like a byte? I don't think so. Even if you did like push AL, right? AL is the lowest byte. It's possible. You can specify these size. Oh. Through side effects. You can push just a single byte, but it will always crash your program based on whatever is called next because the stack will be on a line. Yes, yeah, yeah, that's. You can see this one. But that's more like if you call into libc and you try to use like XMM instructions and shit, is that what you're talking about? Yeah. Cause you can, yeah, you can simulate it, right? Like we saw, we can subtract 100 from, you can also subtract one from the stack pointer. And if you're executing only your assembly instructions, that should work. But when you start getting into other things, some instructions require the stack pointer to be aligned to a certain offset. And so yeah, then things blow up and become weird. Yeah, but I'm trying to see, I don't, yeah, I don't think you can just push one byte onto the stack using the push instruction. Because you can move member around and do whatever you want, you can do exactly the same thing using different instructions. That makes sense. Yeah, I totally agree. You can do it with push. Cool. Awesome. Any other questions before we jump into this, walk through this example? Yeah. One that actually goes back to the example and maybe I just wasn't understanding what you were saying earlier. But you said like when we told subtracted 100 from RSP, so that like if say it had been 10,000, it would now be, well, whatever 100 less of that is. Yep. Right. And then when we write into it, when we do the move RSP into RSI, are we then in a sense writing back up positively in a sense? Yes, 1,000% that is what happens. Okay, all right. We'll see that in depth as we, that's actually the result of, or that causes essentially buffer overflows and what is what allows you to take control from a buffer overflow. Now, the important thing is when we call this or when we execute this instruction, right? The one thing I wanna clarify from what you just said, when we execute this instruction, we're just moving whatever happens to be an RSP. In this case, it'd be 10,000 hex minus 100 into RSI. That's not writing anything yet. It's only when we call sys call that this read system call starts writing the bytes that we input to the program at that memory address inside of our program, so that when it returns from the system call and this next instruction executes, whatever was written get put at that memory address RSP. And because we tell it only write 100, it will only write at most 100 bytes. So it'll start writing at the memory location 10,000 minus 100. Exactly, and it will write starting there and it will, so if we take this example, I don't know, can you see my mouse cursor over there? Yeah. Okay, so it would start, let's say this is minus 100. It would start writing, writing, writing, writing, writing, writing, writing, writing, writing, writing, writing up all the way up and write 100 bytes from there up to 10,000. It wouldn't actually overwrite whatever was at 10,000. So that what we'll see eventually is that what's actually above us on the stack of wherever the stack pointer is, some function calls us and there's stuff that it needs that is stored on the stack. So that's when there's a problem is when a program overwrites what's on the stack above what it's allocated. Right, right, which is pretty cool. Yeah, anything else? This is important stuff. This forms the basis of exploitation and all kinds of stuff, that's why we're talking about. And feel free to interrupt at any time. It's hard for me to be on all of the Discord and the Twitch and stuff, but you know. So yeah, just feel free to interrupt me. I'll let you know if that goes far here. Thank you. There we go. Okay, okay, so we want to... So we're going to execute push a R-A-X. So this is going to be the next instruction that executes. Now, once that instruction executes, oh weird, I adjusted the dollar signs. Now, when that instruction is done executing, what happens? Okay, the first thing that happens is, oh, okay, yeah, okay. The first thing that happens is, eight bytes are subtracted from the stack pointer. So RSP is now minus eight bytes, and this is correct, right? Yeah, so 1000, okay, FFF eight is where we're at now. We subtracted eight bytes, and then we move the eight bytes of whatever's inside R-A-X onto the stack. So now that sticks in memory that stays, and we can now use R-A-X for something else. Cool, so first subtract, and then put whatever's in that register onto the stack. Now, the next instruction is popRBX. So the first thing of pop is take whatever is at the memory address that the stack pointer is pointing to. So FFF eight, take the eight bytes there and copy them into RBX. So what are those bytes there? Well, they're the bytes that represent the hex value zero A.  And copy that into RBX. So RBX changes to OXA, and then we're not done. We need to replace the stack pointer. So the stack pointer, we add eight bytes to the stack pointer. So the stack pointer is back up to 10,000 hex. What happens to this A that's on the stack? It stays there, but yeah, who knows? Yeah, it stays there, but it's, yeah, exactly. From the semantics and point of view of our program, it's now below our stack pointer, so it's functionally garbage. We don't actually care about that it's there, but as we'll see for exploitation purposes, you actually may care that some special value is there. Think about if a password happens to be on the stack, and you have a way to read that value, that can be something that's very cool. So, and so what was the effect of these two instructions? What did they effectively do? Well, could you do what they did in one instruction? What happened to RSP? What was the value of RSP before these two instructions, and what was the value afterwards? It got moved further down, so into the stack. It got moved halfway through, but afterwards we added eight back to it, and now RSP is right back at 10,000 hex where it was at the start, right? Oh, right, so it's back where it started. So this is basically just a long way of moving RAX into RBP, or RAX start. Yes, 100%, exactly, right? Yeah, it's effectively what happened. We're just using essentially, you could like scratch memory to do that.  Cool, okay. That hopefully helpful a little bit more. Okay, cool. So that helps clarify things a little bit hopefully as to why we're getting this garbage, right? We, and so let's look. So we had here, and we're, so we're asking the operating system, remember, because Reed is in the operating system, hey, we want to read from standard input, write it onto the stack 100 bytes. So we do that syscall, and then we say, okay, write to standard output RSP, the stack pointer, onto the stack of that same exact same location, 100 bytes. So man to read, we want to because of that section. Cool, so we always gotta go back to the man page. When we get something weird, that's something that we don't suspect. Let's read the documentation. So read attempts to read attempts. This is very key. This is kind of an important general concept to remember throughout your programming career is programmers typically don't use things like intents or guarantee or can or may or must. They don't use these words arbitrarily. They use them for a very specific purpose. So in this case, when it says read attempts to read up to count number of bytes from file descriptor into the buffer starting at buff, this should give you a hint that, hmm, it may not be successful all the time. So let's keep reading. On file that supports seeking, the read optimization can't convince that the file offset and the file offset is incremented by the number of bytes read. If the file offset is at or past the end of the file, no bytes are read and read return zero. Okay, cool. So if we're at the end of a file, it would return zero. That's interesting to know. If count is zero, read may detect errors. Okay, count is not zero, so we can ignore the rest of this paragraph unless you're curious as to what happens when count is zero. According to POSIX 1, nope, don't care about that. That's gonna be some weird POSIX-y, Linux-y thing. Okay, return value. On success, the number of bytes, ooh, can I do that? Sweet. On success, the number of bytes read is returned. Zero indicates end of file and the file position is advanced by this number. It is not an error, it was important. It is not an error if this number is less than the number of bytes requested. This may happen, for example, because fewer bytes are actually available right now. Maybe we're close to the end of the file or because we're reading from a pipe, which we know about and talked about, or from a terminal, right? Which is our case, we're reading from the user. We have no idea how many bytes the user is gonna send us. They may send us zero bytes. They may send us 100. Or because read was interrupted by a signal. On an error, negative one is returned and error number is set appropriately. In this case, it is left unspecified with the file position, if any, changes. Okay, cool. So this means that, so let's run this again with S-trace, foobar, and we can actually use this output here. So it's calling read foobar in a new line 100 and it's returning seven. Somebody remind us, what was the return value of the read system call? Oh, no, we're being rated by Pone College. Yeah, the return value of read, thank you, is the number of bytes read. And so we're reading in seven bytes and read is telling us that through the return value. And what are we writing? Well, we're telling it just to output 100 bytes anyways, even though we didn't read in 100 bytes. So we actually have a problem in our program, right? This write and there's actually a bad specification so you can blame me, right? I gave you this specification that said, hey, we want to read in 100 bytes, then write 100 bytes. But that's not actually what we want. What do we really want from this program? We probably want it to read an arbitrary amount of bytes until it reaches a new line. Yeah, we may want to just read in until we reach a new line, or we want to, well, if we go back to the purpose of the program, we want to read in up to 100 bytes from standard input and output that to standard output, the amount of bytes that we've read in. So we actually want to do, and this would be, let's say, num bytes read or something like that. So how do we get the return value of read in our assembly program? That should be an RAX, right? Yes, so based on, when we talked about system calls, we call a system call and the return value, is it in here? It must have been in the slides, so let's assume it's in the slide somewhere. So now, after we call the system call, whatever was inside RAX is completely wiped out and the return value of whatever is, the return value of read, which is the number of bytes is now inside of RAX. Where do we want that to end up for this, in this program? Sorry, for this, not program, this system call? We want it in RDX. Yeah, so before, and what if we did move RDX, RAX? So if we run this, what's gonna happen? Let's go here, GCC, echo meeting. It's gonna be one byte. It's gonna be one byte, but I told it to RAX. Oh, sorry, I'm using foobar. Ah, it only output F, what the heck? You already overwrote RAX with your system call. Yeah, so this is the important thing to remember with assembly. This is a good lesson for us. At this point, as soon as I copy one into RAX, I now have no idea what that value is. I can never get that result back. It's gone forever. So what I want to do is before I do that, I wanna move into RDX, whatever was inside RAX. And that way, here, I will be moving the return value. Now RAX here contextually has the return value of read, the number of bytes that we read. Will it ever be greater than 100? Shouldn't be. It shouldn't be, right? Because I told read, I want at most 100 bytes and it returns the number of bytes that it read. So it should be anything from zero to 100. It may actually be negative one in case we hit an error code. So if we couldn't read for some reason, this may cause problems, but we'll ignore that for now. So let's compile it, run it foobar outputs foobar. Let's double check. Boom, and now we can see that's so cool. We're capturing this return value here of seven and passing it as seven here as the parameter to the right system call. Is that awesome? Say yes, type in chat, yes. People say yes. It's very awesome. Thank you. So weird, this is even worse than Zoom. One more time. I don't know what, you can't, I never remember what I say. Apparently it needs to be repeated. Oh yeah, so we're actually taking and capturing this return value and dynamically passing it to the right system call. So that if I do type in some other junk, here it was 21. Boom, it gets to be passed in 21 here. So we're only writing out exactly the bytes that we read in, cool. Now, what if I do something and type something in that's really long? How come that, well. How come that didn't write out? So here's what it wrote out. How come it didn't write out everything that I typed in? It was more than 100 bytes. More than 100 bytes, exactly. Okay, cool. So our program kind of sucks, right? It only reads in 100 bytes and outputs that. So, how do we know how much input there is? Like why don't we just change 100 to be 1,000 or 10,000? That leaves space for people to mess with stuff. Yeah, it leaves, it may lead and have a lot of weird space, right? It may, it is kind of like fundamentally the problem is we have no idea how much input. What if it's a gigabyte? What if, is it possible that we may want to have input to our program that has output more memory than we even have in our system? What if we have 10 gigs or a terabyte, right? Our program should technically still work. It's very simple. Just take input in and cat it out, like the cat command. You wouldn't want the cat command to fail because of some weirdness. So we need some loops. We're gonna go back to our old friend, loopy loops in assembly. So if we go back, we had conditionals, right? To compare things, and then we have this nice table of jump if equal, jump if not equal to, jump if greater, less than, less than or equal to, blah, blah, blah, blah. So let's go back to our handy read function. How do we know when we're done, when we have no more input? Let's go to the return value. Is it return zero? Yeah, exactly. So it's kind of interesting if you think about it, this read system call, right? If it just returned zero when it didn't read any bytes, you wouldn't know, does that mean because there's no more bytes to read? Like if we're reading from a file, have we reached the end of the file? Or is there literally just nothing more to read? And that's why when we call read, that's why read will always wait. And as long as it will wait and hang our program until we get at least one byte from that file descriptor. So that's why we're reading from standard input. That's why we're reading from standard input. It actually waits until it has at least one byte. Cool, okay. So we have our condition. We wanna keep calling read and write. So let's go back to our code. So we have our read, have our write. And what we wanna do is after this read, we wanna check, hey, is now, okay, we can do two things. Let's call this. So in assembly, we can define things as labels. So here I'm defining a label called exit. All that does is reference this code. So the important thing to remember when you're thinking about and doing assembly programming is labels don't actually mean anything. They don't get compiled to anything in the code in the program in the assembly itself. Exit, this becomes a label that I can then reference later in any place in the program. And so I'm gonna create a label called start. So this is kind of at the start of our, what's going to be our loop. So when do I want to exit? So how do I, so let's go back to this slide. So how do I use these insane things to create? So first, what am I comparing it against? R-A-X, right? Yeah, so I'm comparing R-A-X. What do I wanna, what is my case? So let's write it here basically like, if R-A-X equals what? So what's the value of when we want to quit when we're done? There's no more bytes to read. It was zero. If zero, yep. If R-A-X is zero, then go to exit, right? And if not, if R-A-X is not equal to zero, then write and go read again. All right, cool. So we need to compare this, and man, it's been a long time since I've written X86 stuff. So we should be able to what? Compare, I think we need a zero and we need a register. We're not using RBX for everything. Move zero into RBX, compare R-A-X with RBX. And then if they're equal, so jump if equal. And just compare the immediate value, R-A-X to zero. Does that not work? Probably, I have no idea. Let's try this. Comment to that. No, yes, we can. I'm gonna look at the assembly instruction here. Boom, oh, see, and we can see I actually have my labels here. So it shows up as a label, but it doesn't actually affect anything here. So yeah, I compare R-A-X with zero. Oh, sorry, the syntax is weird here. That's fine, we'll look at it a second. Compare R-A-X with zero, jump if it's equal to exit. Cool. Okay, so let's run this and see if we got this. Yeah, dash M Intel. That's only for people who are so lame Connor that they can't do multiple syntaxes at once. Okay, so did foobar foobar? Does this mean my thing passes? But I'm good. It's my test valid. Good morning. Well. What was the problem with this test I just made? It doesn't give you more than 100 bytes. Exactly, I didn't test the condition that it's more than 100 bytes. So the program worked, quote, quote, worked, but we didn't actually test what we wanted to do. So I'm gonna just put in a bunch of input and it only output this much, it didn't, and then it, the annoying thing is it took my input and then tried to feed it back into the shell, which is very annoying. Okay, cool. So that didn't work. We have to go back to the code. This is a pretty good way of approaching your code, make small changes and that you think will implement something and then figure out a way to test it, go test it, test that condition, make sure it does what you think it does, and then make sure you try to test things that it shouldn't do. Okay, so what's the problem here? How come it didn't, we gave it more than 100 bytes, how come it didn't go back into the start? I guess another question is how do we figure this out? How do we think about these? We need a label that goes back to start. So we have the label, but we don't have anything, a dump that will send us there. Yeah, we haven't altered the control flow at all, right? So if you think, and what you can do is actually walk through these instructions. Okay, subtract 100 from RSP, move all these values in here, call system call, which should call read, great. I called read, let's say I returned 50 bytes, compare Rax with zero, is Rax equal to zero? No, so we don't jump, we fall through and go here, and so we go, okay, move Rax into there, move one into Rax, move one into RDI, move RSP into RSI, call syscall, great, this calls right, we already checked that, and it also specifies the number of bytes read which comes from Rax, excellent. What happens after the system call? Not quite nothing, what's the next instruction that gets executed after the system call? Rax 60. Move Rax 60, move zero into RDI, and then syscall, which calls exit, right? So just like this system call, the thing that happens is the next instruction, and then the next instruction, and so the problem is we have nothing that goes back to the start here, right? We essentially accidentally fall through and go to the exit case, which is not what we want. So it should be, is it just J? Or is it branch, is it a BR? You want, what, are we not doing it? Oh, your branch, okay, remind. Yeah, so we just wanna always go at the end here as after we call write, yeah, we wanna go back to start to call read again, check the return value of read, and then call write again, and then go back. So this is where we get the loop, where we're actually jumping back into our code and control flow, the CPU will start executing start over again, and where we've made a loop, hopefully. Hey, jump, JMP. Ah, what is it doing? Did it break? I typed in foobar, it output foobar. I type in foobar enter, it outputs foobar enter. Yeah, it's looping just like we wanted it to. REX is never zero, but let's say. Do I do anything? Nope, okay. So let's look at why. I did control C to kill it, because I think it's important to look at this. So I can say foobar, read, write, hello. Now the important thing here is it's actually reading and writing my slash N, so that's actually my new line character that I'm typing in, and that's why if I just hit enter, it actually is reading, it's reading one byte, and that's the enter character. And so that's why it writes out an enter character of another byte. Thank you in the chat for my nice shirt. This is one of my favorite CTF shirts from the order of the overflow.  So how do I man to read? Okay, blah, blah, blah. The, so zero is when we're actually at the end of file. Right, so where does it say that again? So blah, blah, blah, blah. Zero indicates end of file, cool. So how do I, so now, how can I tell it I'm done? I know control D usually works, I think. It definitely does, so I can hit control and then D, and then I'm done. So what actually is happening here is control D, some special functionality. Supposed to simulate or send the end of file. I don't know if character is the right word, but right? Yeah, so let's see. So one thing I wanna show is if I do echo hello and I pass that into a.out, our program, we can see it actually works just fine. It reads it in and writes it out, right? Just like cat, which is exactly the same behavior as cat. Yeah, I can even do new lines, perfect. Right, all that stuff works. And we can actually look at S trace, we can run it here and we can see we're again reading from standard input, writing the standard output, and look, this is great. We actually get our read. So this is a read where it returns zero saying, hey, I've read zero bytes and it properly exited, cool. Well, let's do that again with our input. So I'll type in foobar and then I'll type in control D and I'll see that there. Okay, what's happening is we have to think for a second when I'm running a.out here and I type in foobar, what's waiting for my input? Yeah, from our program's perspective, it's calling read which is the operating system, right? So the operating system is getting invoked it's reading from standard input, which in this case is coming from us, the user. Now the problem is read didn't specify what characters I can read in and what their values are. So we can't use something special like, hey, when you see a null byte, when you see a zero byte, that means I'm done because we can have files with null bytes, we can have files with any kind of bytes. And so to represent that, what we need is when we do control D, we're actually telling the shell bash that, hey, I'm done now giving input. Consider my standard input that I was typing in at the quote end of file. There's no more bytes that I'm gonna send. And I believe if we search for bash and file, yeah. And da, da, da, da, da. See, when you press control D, the terminal signals of blah, blah, blah, we've reached the end of file and this is great. So then the operating system knows to do all that and it is excellent. So you can look at that, whatever. This is a kind of a nice general tip for any kind of system you're working on. This is for almost all command lines use this kind of thing. So you can learn for, oh, on Windows, blah, blah, blah, this is how you input end of file. Or on your, I don't know, I think all of you like young whippersnappers use like visual studio code or whatever. And so like, how do you type in an end of file in the console that exists in visual studio? I would assume it's control D, but who knows. But anyways, cool. So yeah, using that, we just were able to write our own version of cat. So we could say cat and so see I can use it just like cat. Anywhere I was using cat to read from standard input and write to standard output, I could use that. And we did that. So now that we've been able to write a program to echo all of the input as output, now I want you, this will be a fun learning exercise. So let's write a program that writes the string foo bar to a file called foo. So what's the basic outline here? So we have the man to open. We want to call open with a path name parameter and flags. And we're gonna do that. So we're gonna open. And if we do open, what's the bup bup bup? The open system call opens the file specified by path name. If the specified file does not exist, it may optionally if Ocreate is called be created. So we'll need to make sure we specify this flag Ocreate. I'll help you with that in a second. The return value of open is a file descriptor. Just like the exact thing that we were talking about that we were using of standard input and standard output, right? Once we have that, we can pass that file descriptor to read write close is the alternative of open. So we read it and then open it. And yeah, so okay, things we'll need from this. So we'll need, we had our hello world example if you recall and we had our hello world example. So this will help you with the strings. So let's call this open file.s. I will steal all this from here. And I will make, okay, text global is what we need so that it knows that, hey, I want you to start executing from main. I always like to end with exit. This is always so nice. And now let's just like we did before with echo. Okay, purpose of program. Open a file called foo, create it if it does not exist and write the string foo bar to the file. Okay, so what strings do I need? Do I need the string hello world new line? Yeah, don't need that. What strings will I need? Yeah, I want the string foo bar and I got to change the label to be foo bar. And oh, do we say we want it slash n? Sure, we can add a slash n to it. It's usually nice to do that, but okay. And then we want another string of foo. So foo will be the file that we wanna open. Right, we have the exit. Now what we'll wanna call is open foo. And the question is we have these man to open. We saw that open has this flags parameter. The argument flags must include one of the following access modes. Oh read only, oh write only or oh read write. These requests opening the file read only, write only and or read write respectively. In addition, zero or more file creation flags and file status flags can be bitwise or in flags. The file creation flags are oh close exec, oh create, oh directory, oh Excel, oh no CTTY, no follow, temp file and truncate. So if you want to learn about all of these beautiful flags, you could go and literally read, I see as I'm scrolling this, you can see that there's a ton of flags that you can specify here. All the ways that control, how your program is asking the operating system, hey, to create that file because for instance, so the one we're interested in, oh create. If path name does not exist, create it as a regular file. So it's kind of interesting that if you think about it on its face, the system call of open should be very, very simple. So if you think about it, this system call should be very, very simple. We have, we're calling open, we're specifying a path name and we're just like, hey open this file for me, but what do we wanna actually do with this file? Do we want to read from the file? Do we wanna write to the file? Do we wanna both read and write from the file? What if the file doesn't exist? What should we do? Should we create the file? What if we open up a file for writing, but there's already content in the file? Do we wanna make, truncate the file, make it be zero bytes?  And this is why you have all this insanity in terms of flags and all of the return values and all of the cool stuff that can happen. So what we're doing here is, okay, so we need the ocreate flag because we wanna create it if it doesn't exist. And we want, so ocreate, and we want, what did it say? Okay, cool. And owrite, so we'll do open it with read write, it doesn't really matter. And it said bitwise or, so we actually need to order those two values together. Now we need to look up, what are these values of ocreate and oreadwrite? So for this, I would open up my hand dandy ocreate value in Linux, I don't know it off the top of my head. There we go. Oh God, these are in octal, that's so annoying. That's okay. We'll see if our assembler supports this and oreadwrite is o2, okay, cool. Yeah, so this is what's tricky if you're not used to readings. Can somebody verify that that's correct? This is octal, right? That's octal, escape sequences and double quotes. C, octal, or literal. I think it's, you start the number with a zero. Okay, that's why I thought I just wanted to be very clear. Yeah, so we were talking about bases when we talked about hex being base 16. So every digit represents zero through 15. Similarly, octal is eight. So that's why we're getting different values here. Cool, okay, so yeah, this was what I thought. So beginning with zero, yeah, that's why zero, one, one. Isn't that a Python thing? Is that a C thing, Zion? The O, zero, 10. Yeah, it's a Python. It's much better, it's much clearer. This is insane, it makes you think that like, oh, maybe this value, but we can check.  Okay, but we can actually just use these values. Actually don't care. The important thing is when you're writing the C code, you actually don't care what these exact values are. It actually only matters to talk to the operating system. And your C program would have a substitute in the values at compile time. But we just stole the values from some code. We think they're these. Let's use them right now and see, hey, maybe these are the same. So, so this will be, okay, we'll look at open. So open is two in RAX. So, and move into RAX two. That's open. So I need the file name. So the file name I wanted was foo. So move into RDI foo. And now I'm gonna do something tricky. I'm gonna say, well, not really tricky, but let's move into RSI or the flags, RSI. This, and it needs to be, they said bit-wide OR. So I think I can just do OR into RSI 02. And that should take whatever's in RSI or it with whatever's in 02, and then put that value into RSI. And, okay, this is saying I need a mode. So now I need to actually read about the mode. The mode argument specifies the file mode bits when a new file is created. This argument must be supplied when O-creator, O-tempile is specified in flags. Great, okay, we specified O-create. This means as a little hint, this is the permissions that are on that file. So this is what we're setting here. For now, we actually know we can do octal. I think it's, yeah, 777 should be just handy-dandy fine. But this needs to go into RDX. Let's go back here, remove RDX and syscall. Okay, so this should create a file called foo. So let's compile this bad boy. And, okay, and this was called open file. Wow, guys, I'm really good at naming things. Okay, cool, aha, I have the same problem before. While I'm doing this, Zion, can you check out how to, I can't remember, how do you reference these things in a PIE? Do I have to use like RIP plus or something? Do you mean the jump where what? No, the problem is this label. So, yeah, using this label when I just move it in here, it obviously. We'll move the address. God damn it, did that work? Yeah, it did. See, man, I don't even need you. Why are you even here? Dang, it could be me through the punch. No, I didn't know that that would work, but basically this is how you would reference and let the fact that foo can be anywhere. So RIP is the current instruction pointer. So this actually calculates the memory location that foo will be in relative from the current instruction pointer. And that's so that the program, when the operating system loads this program, it can actually put that memory and move it anywhere in memory. Whereas before when we said, hey, don't do position independent code, compile it at fixed memory locations. So this actually helps us and it means that we're writing nice code that will be future perufe, which is super cool. So, okay, so yeah, we have loading that into there. Cool, so look at this. And we just made, and look, again, so we called open with foo. We passed in, oh, read, write, oh, create, 777. And what's this return value that opened returned? It's the file descriptor. It's the file descriptor. Yeah, exactly. Which makes sense. Why did this make sense? Because I just said that it makes sense. Because that's what the man page said. It is what the man page says. And also, what are the file descriptors that we know about? Zero, one and two. And so the next smallest open file descriptor is three. And that's why it returns it. I don't know that that's officially part of the standard, but it is normal behavior of most operating systems that I've seen. Okay, yeah, question in the Discord. Do we have to close it? We should to be good people. But when we call exit, because remember, who knows? Who's keeping track of what files we have open? The operating system. The operating system, exactly. So when we tell the operating system, hey, I wanna exit, I'm all done. At that point, the operating system actually will close all of the open file descriptors that we have. So in this case, we don't have to do it, but yes, in general, that way, if our program, as soon as your program is done with a file, you should close it because you don't need that anymore. Okay, this is sweet. So we did this, and then we called syscall. And now we want to call right into the file descriptor that we just got, which is in where? The Gasp at RAX. Yeah, into foobar. And how many bytes? One, two, three, four, five, six, seven, eight. Eight bytes. Cool, so this is when we switch to me doing stuff, to y'all doing stuff. Cool, so finish that. Implement that right function. Stop streaming that. I need to switch this OBS over. Okay, and for those of you that want the flag for today, it is now up exclusively on the ASU Hacking Club Twitch, right above me, QPU. Feel free to ask questions. Oh, somebody asked the difference between test and CMP. I have no idea. I have to look it up. I literally don't know. Sorry, I wasn't asking about the difference, but why is test use versus CMP? Yeah, I still don't know. This is a fascinating Stack Overflow response. I think the main thing is that test EAX EAX is shorter than compare EAX with zero, so it uses less bytes. So it's a performance optimization. Yeah, exactly. Okay, thank you. Yep, hey, Zion? No. Is the invite for the Discord still in the browser, like mentioned on the website? Yeah. CryptoMathican is wondering. Oh, cool. But it should be. Be really sad if it wasn't. But that just gets access to the public space. Man, people are making millions of dollars doing Twitch as absolute insanity. The invite's still there, and it's still very real. Cool. Why is Twitch turning my smiley faces into robot smiling?  Man, I'll never understand this thing. Pretty sure it's because robots are gender new. I have a question. Shoot. I did read it right like we did in the Echo Meeting script, but obviously passing RAX into RDI, which is our file descriptor. And then I used the RIP addressing, so RIP plus foobar. But when I run this whole thing and I do an S-trace on it, it tells me that I've got a bad address, a bad file descriptor. Did you do LEA instead of move? No, I did not. They're all moves. For the RIP plus foob? Oh, does it need to be an LEA instead of a move when you use the addressing? Exactly. Because a move would say calculate what's at RIP plus foob. Whatever's at that memory location, move those bytes into RDI. What you wanna do is calculate what's the value of foob plus RIP and then move that into RDI. So it's like the pointer equivalent, yeah. Okay, thanks. Yep, look at this, Zion. We got Discord, I mean Twitch people making their way into the Discord. You're starting a revolution. I know there's two, what? Yeah, we have a public session, right? Like what? In Discord. Yeah, yeah. We got a public channel and we also got a public challenges channel. Yeah, so crypto, mathikian, mathikian. Yeah, welcome, we do it. We have a public thing. We also have public challenges. If you wanna dig more into this and learn more, happy to hang out. We're doing this weekly at five, five Wednesdays. Yeah, no voice channel at the moment. Currently a member's only thing because we're an ASU club. But feel free to, you know, you can ping and chat with our illustrious president, Zion, AKA Mahalo's, who has always got an ear for your suggestions, right, Zion? Yeah, yep. One of the suggestions. Give me the suggestions. I don't know. I mean, also if you're whoever is in that public channel, it's pretty neat if you get the membership challenge because then you'll be one of the people on the membership board who is not a real ASU student. You can forge your own signature. Oh snap, gotta hack your way in. Exactly, you gotta hack your way in. It's the only way. I think as of right now, there's only one person on the list who is either not a real ASU student or is and didn't want to verify they were real. Everyone wants to know. That's great. And they didn't try either. If they didn't put like a fake signature, they just put nothing. But I actually encourage all the fakers to put a fake signature so nobody really knows. Yeah, then they have to verify it with the public. They really want to know who the real members are. Nice, I like it. All right, sweet. We got three people done, it looks like so far. When you got it, yeah, I figured it would just be easy thing to just make a little reaction to that message I wrote when you're done. That way I can keep track. And we'll probably sync up and let's give it maybe 10 or five more minutes and then we'll go through, finish this off. You guys are working your way up, becoming real assembly programmers. And as you're doing this, think about how this used to be the only way to program. You could only write assembly, is that insane? No fancy Java or C++ to hold your hand. And you got to actually move those values into registers. And if I can pontificate a little bit more, this is understanding how to program a machine at this kind of low level, right? Moving things in, moving things out. This is what is used for things like programming Rop. I mean, basically the people have described exploitation as programming a weird machine. So basically you're reusing little bits of functionality of the program to do something it wasn't supposed to do. Or like with heap exploitation, you're getting the heap into this crazy configuration that it wasn't meant to do. And that's actually what enables you to, that's like at really at the heart of exploitation is getting a program to do what it wasn't supposed to do. But in order to do that, you need to understand how to make a program do what it's supposed to do, right? So it's these concepts of doing these types of things. Programming these, you know, X86 is a weird machine. It's just the one that most of our systems run right now. And so we're used to reading it and understanding it. But these concepts apply to many different areas. I guess to abuse Yon's cruddy kid kind of metaphor, this is kind of the, you know, you're on the practicing, whatever, what's it called the wax on, wax off, right? You're doing what seems to be mundane programming things, but really there's a deep thing that when you really grasp how to understand and program a machine that applies to other aspects of hacking. All right, we'll sync back up in five minutes. All right, let's see, we're at five people. It's pretty good, we got roughly 50%. All right, shall we continue? All right, we have, yeah, five people done. We'll kind of wrap this up here. See, do I want to give you any homework? I don't know, did anybody actually do the homework last time? Cool. I totally did. Yeah, some reason, hey, that's fine. That's actually 100% fine. It doesn't matter when you do it, right?  You can, you get out of it what you put into it, right? I mean, Xion, did you get to be leaked by going to meetings and following along in the meetings that we had? No, I guess not. I had leaked from the content from the meetings and I would work every weekend to get better. So I guess it was self-studied more than anything. Yep, playing CTFs. I'll push you the right way. Yeah, exactly, like the purpose of the meetings is to exactly do that, right? Give you an opportunity to guide you, right? That's what we're trying to do here, what I'm trying to do is to guide you through these topics starting from somebody who literally knows nothing, right? To now your writing code to open and write files and learning X86 assembly in the process, which I think is super cool. And so, yeah, that's the goal here. But it's only question and discord. Elite is quantifiable. Would you guys know how you become a hacker? There's kind of a famous way of how you become a hacker. Anybody know? Well, I don't know this one, what's the answer?  So it's one of those things, you can't call yourself a hacker. You can only have somebody else call you a hacker. And that person themselves, if they are a hacker, of course, you have this chicken and egg problem of, yeah, exactly, in the chat, who was the first hacker? I think it's probably a group of people, but yeah, it's kind of a similar concept in terms of LEET. So I think it's honestly pretty lame to claim that you are LEET. You kind of know if you are.  So that's kind of what I think about there. But yeah, that's a good question. Cool, okay, let's speak of LEET. And the only way we get there is by practice. So that's what we're doing here. Cool, all right, let's do this together. If you're stuck and got stuck at a point, and then follow along, see where you got stuck. Feel free to ask questions of why, like this way it didn't work, just like we talked about, right? If you change this load effective address to a move, you're gonna have problems. Okay, so now I wanna call write and I wanna pass in the FD as the second argument, the FD that we got from the open system call. I then pass in foobar and I'm gonna pass in eight. So what's the first thing I need to do?  I'm not gonna just write this again from scratch, but I have my echo function here. I already have a write function. Why the heck would I start over from scratch? Cool, so I know from here, I'm gonna need to move into RAX one. I'm going to need to move into RDI. So what I wanna move into RDI, so let's look at the, I've already lost the thread. RAX was the number, so this was write. RDI was the first argument. RSI was the second argument and RDX is the third argument. So RDX is pretty easy. My third argument here is just eight. So I'm gonna move eight into there. I move one into RAX, but how do I put this file descriptor in the first argument, which is RDI? So again, I don't wanna write, I hard-coded one because I wanted to write to standard output, but now I wanna write to that file that I just opened. Yeah, move RDI, RAX, thank you. But before I overwrite it, yes, thank you, look at that. You're already anticipating all of the questions and stuff that come up, right? So we first move RAX into RDI, setting this file descriptor. I move one into RAX, I load effective address into R, now it's not RDI, it's the second argument, so it's RSI and rip plus foo underscore bar, if I recall correctly, yep. And then what do I need at the end here? Sis call, yes, thank you. All right, so now let's test that. Let's cat out, I have the file foo, so there's nothing in there right now. I can do LSHLA foo, it'll show me there are zero bytes in this file. GCC, I shouldn't need that. Yep, run eight on out. I always like to do S trace eight on out. Oh, look at this, this is beautiful. Open foo, read write, create 777, write to file descriptor three foo bar slash n eight bytes. If I do LSHLA foo, I'll see there are eight bytes in there and if I cat foo, it'll say foo bar and if I hex dump foo, I can see those bytes.  Okay, yeah, this is much better. F-O-O space, remember we were looking at hex 20, it's a good one to remember as space B-A-R new line. Boom, those are those eight bytes in that file, awesome. Now, what I want you to do is pretty easy.  That purpose of program, write to standard and make sure this compiles so I don't give you some, this is writing the standard output, shouldn't take you too long. All right, look at that, getting better and better. All right, everyone say bye, Twitch, see you all. You know what I gotta say, it was actually fun chatting with people on Twitch. I don't understand any of the emojis that you guys use, but you know, I can learn and yeah, see y'all next week. Whoa, it's a cool one to end on. No.


During such events as a pyroclastic flow, complete human forms can often be preserved in a fixed position, turned to ash in an instant. Someone turning into a stone fossil with age, however, was thought to be an impossible scenario. That was until 1898, when an extremely controversial discovery was made, deep within a copper mine.  Deep within an old copper mine in Chukikamara, an ancient stone woman complete with basket and tools was discovered and although a date of only 400 years was preliminarily given, it is clear to the many involved that she is far older than that. The discovery was examined closely by Jose Torrobino Medina, a central figure in Chilean archaeology at the time. He described his findings as follows. The body is that of a female. The depth of the soil where the corpse was found was no more than 6 to 8 feet and the miner was probably searching the mountain when a sudden collapse buried her. The miner, feeling that the mountain was breaking down, lifted her arms up to protect her head. The position in which her body is preserved. This discovery, although the only one of its kind, is highly controversial and we suspect this may be because certain individuals are aware of its true antiquity. Beside the body were the remains of a basket, a stone sledgehammer, several stone shovels, sharpened pieces of wood and a torn bag made of animal hide, all leading to the conclusion that this mummy dates from a very distant time within our history. After more recent analysis was conducted, it was discovered that it was actually a man, strangely. He also has an unusually shaped skull, and a green hue from sulfate and chloride within the copper. It is thought this may have been one of the contributing factors in his marvelous preservation. The copper man of Chukwikamara is extremely difficult to research, and although he is clearly of considerable historical importance, his whereabouts may continue to remain vague. Regardless of his known whereabouts, his existence will forever lend credence to a forbidden history here on our planet. Edinburgh, Scotland, a very ancient land with a castle built upon an extinct volcano. Many mysterious things lay and possibly live within Scotland, the most famous of which undoubtedly the extremely elusive Loch Ness Monster. However, recent surveys would suggest that among the most popular of attractions are in fact its vast collection of, to the well-trained eye, extremely ancient coves and cave systems.  And hidden behind a modest door on Drum Street in Gilmerton is quite possibly the most incredible network of them all.  And thankfully, due to their popular attraction with tourists, often the explorers amongst us, many open-minded individuals, have often been left with a sense of discomposure regarding the officially upheld explanation for their origins. As such, and rather predictably, many alternative theories often involving a far more ancient origin for the cove and its purpose now abound. The mass-regurgitated view regarding the construction would suggest that a blacksmith by the name of George Patterson, who actually resided within the cove within the 18th century, somehow created them alone by hand and within a mere five-year period. With even George himself claiming to have cut this extensive, elaborate, and unquestionably enigmatic underground structure using simple hand tools. Since the claims three centuries ago, however, numerous holes have been seemingly discovered within this popularly upheld sequence of events, fueling the already prevalent suspicions within skeptic parties, maybe in an attempt to hide its true antiquity, as we experience so often during our research. On Wednesday, the 15th of August 1906, a front-page column by a writer known as Fr. Coles for the Scotsman dug into George Patterson's version of events, commonly referred to as the tradition. Coles found it to have been nothing but a fictional fallacy, possibly created by George himself in an attempt to profit from deception. It seems Patterson not only accomplished the seemingly impossible, excavating hundreds of tons of stone, but also it seems he successfully went unnoticed by the entire surrounding population during this entire procedure. Just who could have built Gilmerton Cove? When was it built? Why did they build it? With modern radar scans of the surrounding area, indicating that even more systems lay close by, still undiscovered, possibly isolated by ancient cave-ins, you have to wonder, could the Gilmerton Cove be far older and originally far grander and extensively larger than anyone today could have ever possibly imagined. Will we ever solve the mystery of Gilmerton Cove? It seems only time will tell. When someone mentions the word Jurassic, visualizations of enormous creatures surrounded by man-eating plants will soon follow. And this is for good reason, because during the era of the dinosaurs, enormous creatures could only survive with equally enormous food sources. Within the Black Hills of Dakota, petrified remains of these once enormous organisms can still be found. Presumably, they can also be discovered in many other parts of the world, yet within the Black Hills, it seems the prehistoric remains have avoided the deluge of sediment, which has been experienced elsewhere, subsequently bearing the evidence under several meters of Earth. Petrified enormous trees that, when alive, would have soared into the air, matching in height many of today's modern skyscrapers. Open to the public in 1929, an entire island, 50 by 100 miles in size, covered with the perfectly preserved petrified remains of a once gigantic forest. Trees of incredible and seemingly impossible sizes, destroyed by a cataclysm which made them collapse in unison. Now recognized as one of the largest outcroppings of fossilized petrified wood anywhere on the surface of the Earth, it is a rare natural insight into the enormity of Earth's ancient wildlife. Quote, Here is just the beginning of an astounding photographic documentation of this petrified island, a little glimpse of an entirely unknown condition upon the Earth. It is a major historical discovery that, if embraced, will cause major upheaval within the science and religious communities. Said Joseph C. Bennett from BeholdGiants.com. Scientists assume that the maximum height of a tree was 425 feet from the ground. At this height, the tree's ability to pump nutrients is supposedly overcome by gravity. However, Joseph, along with several other astute researchers, have discovered the remnants of ancient trees within the area which would have had a circumference of over a half a mile. The Devil's Tower, coincidentally also within Dakota, has been argued for many years by many people to actually be that of a once enormous petrified tree. The formation of its rocky surface does indeed appear to be reminiscent of tree bark, yet many will argue against such a premise or indeed the possibility, based on traditional rather than more modern and controversial understandings of the past capabilities of plant and animal life. Thankfully, as more research is undertaken and more become aware of these amazing places, the possibility becomes even more likely. The channel's recent exposé regarding the possible true age of the Great Pyramids outlaid many fragments of evidence, strongly suggesting they predate a number of past advanced lost civilizations. However, it mistakenly overlooked a possible culprit for their construction. These layers of casing stones, each once an enormous undertaking, occurred at varying times within antiquity, by different civilizations which many perceive were possible conservation efforts. Due to this, and the fact that I had so far identified at least three advanced separate civilizations elsewhere, achieved through the cooperation of nearly three years' work, used upon cataloging unexplained advanced ruins from the past, characteristics within the techniques used to construct them, toolmark signatures left upon the stones, unique identifiable architectural design, and differentiations exclusive to particular ruins were slowly gathered and used to identify three distinct ancient civilizations with their own unique directions of development. However, I mistakenly presumed that the Cyclopean civilization was placed far closer to us than the original pyramid builders. This was put forward as a personal opinion, which mystery history reluctantly has to admit that, although based on logic, has been disproven by this very same methodology. In the video, it was stated, and I quote, I have never, and now strongly feel will never, find any indicative evidence of these civilizations building the footings under any of these gigantic megaliths. I had looked for a significant time for any signature stonework, linking any of the civilizations I had identified to the placement of megalithic blocks over or around the 1000 tons mark. If I discovered these characteristics beneath such enormous stones, I would have proven that they were indeed capable and more than likely the civilization responsible for their placement, with the most significant being the building of the pyramids. There were some issues which niggled MH regarding this postulation before the following discovery, however, due to the lack of any footings, had to postulate the pyramid builders were a far more capable group. In such niggle were the matching scoop-like tool marks used by the Cyclopean civilization found in Bosda Cave, Turkey, officially proven to have been the quarry for Haran, a nearby settlement, which possessed their signature Cyclopean blockwork, cuboid blocks with a raised center, synonymous with many ancient builds, with the same scoop-like tool marks also present upon the excavation of the unfinished obelisk. Due to the absence of footings, which would have demonstrated undeniable proof that they were indeed capable of working, moving, and placing such stones, I wrongly presume that they were incapable of such tasks. However, unlike academia, regardless of disliking the realization that he was mistaken about something, the motive of the channel is honest research and logical deduction. Thus, admitting one's mistakes allows not only mystery history's understanding to evolve, but is the only path one can take in the pursuit of truth. The Western Wall, Whaling Wall, or Kotel, as known in Islam as the Barrage Wall, is an ancient limestone wall in the old city of Jerusalem. Originally erected to its current height by Herod the Great in 19 BC, enclosing the Temple Mount in a large rectangular structure, topped by a huge flat platform. The Western Wall is considered holy by both practicing Muslims and Jews. Of the four retaining walls, the Western one is considered to be closest to the former temple, which makes it the most sacred site recognized by Judaism outside the former Temple Mount Esplanade. Just over half of the wall's total height, including its 17 courses located below street level, is academically claimed to date from the end of the Second Temple period, and is commonly believed to have been entirely built around 19 BC by Herod the Great. However, the Western stone, weighing around 600 tons and a few other enormous stones, all located below ground level within the base, not only possesses compelling evidence of incredible antiquity, but beneath this enormous stone are the signature blocks of the civilization I named the Cyclopians. This is evidence I wrongly presumed I would never find, demonstrating that the civilization I call the Cyclopians were indeed capable of moving such gigantic stones. What's more, they were also capable of moving the pyramid stones, and indeed those of Baalbeck, yet to be a viable suspect, due to the immense age of the pyramids, evidence which would need to be found to support this, and amazingly, these foundation stones do indeed contain just that. Still embedded within holes, presumably cut for the placement of the blocks, timber chocks can be found in these foundation stones, wooden planks which have over an unimaginable amount of time petrified into coal, stone, and flint-like materials, indicating a minimum age of at least 100,000 years. As such, decay and petrification would not have been able to occur in the currently attested timeline. Could these stones date from the original construction of geese's great pyramids? It is undoubtedly a wall many followers of certain Abrahamic monotheistic faiths hold in high regard, and one of incredible importance to them. Additionally, however, due to these amazing features, it is also of high significance in regards to unraveling the secrets of history. It is undoubtedly highly compelling.