 Hey guys, welcome back skits own lab three Topic today is going to be implementing a very simple program one that you can execute like this you'll pass in a numeric quantity and it should generate a password of that length consisting of Letters numbers and symbols that's the idea So not a particularly challenging task one that you might lean on Python or bash or some other scripting language to implement But I tell you perhaps assembly should be one that you consider as a language to implement this simple program sometimes people talk about assembly in terms of Use for reverse engineering stuff or for some minute Performance advantage of some inline code. They're gonna write for their c-program. Yeah, maybe But it's also the way we're writing it in this series very very applicable to these small one-off functions that you want to be small fast simple easy to understand a low memory profile and also like absurdly portable like a binary that we generate in this way can literally be be emailed to your friend as long as he has Linux for this I should say the same OS as you either BSD or Linux and Also runs on x86 hardware it will just plug-and-play work. So for those reasons, I would like you to consider assembly for these simple one-off scripting language type problems like password generation and So for this is very simple. We have just a few Includes in fact only three and we've made all these in previous episodes So first of them was rand int. So obviously for a random password We have to be able to pull random numbers somehow and so that's what this is for you pass a lower bound and upper bound And it returns a number in between hopefully Also, we have to be able to parse integer well parse strings for ints. So we're gonna pass in a number So we type in program space to eight Enter it has to parse that character You know array of two eight into the number 28 and also this function can handle base 16 8 and 2 But that might not be useful for us But it's cool nonetheless. So yeah, this just takes a pointer to that array and then returns the value in rex and the last Include we have is a very simple and perhaps not efficient but simple non-buffered printing routine called print ASCII just takes a File descriptor in our case going to be the console. So to send it out as well as the character you want to print in our case that particular random character and It drops it out with a syscall. So this particular Function is not one I would use in a bigger piece of software But for a small piece of software, I would use this like this one for and why is that? Well, it has one syscall for every single bite each bite is being written directly One for one with a syscall, which is not efficient. Typically you'd buffer these all together because syscalls are slow but in my opinion the trade-off of this very small print function versus having a you know 4k 16k whatever print buffer and all that buffering Logic, it's just not worth it for these small one-off programs. So yeah, we'll use this one today Let's get into it so In the Suppository you have a couple of folders all the labs are in the lab folder Once you download the code if you choose to do so run make bins that creates this bin directory with Some useful binaries including the first one there make executable. That's like chmod We made that in like episode like three or something. You can see it's a very small Hold on It's only like a hundred so bites to make a Binary executable we use that in our tool chain essentially so you'll need that and then We'll go into that lab folder Well that folder we have a template that says to bare bones Return zero program so we'll go into there. Actually, I'll copy that first We'll make a I don't know Password folder from that template Go in there in there we have two files one of them is the compilation type of script I'm gonna go into that really quick. What does that do that? Basically it runs NASM on our code Pulse some OS specific includes because there's different Numbers on BSD and Linux, but ignore that then we run our make executable binary on that binary to turn it into an executable binary and then lastly if we run it of course, I think for our particular implementation right now You know, we're gonna say the program and then a number so we could put that in here like a binary eight I'm just gonna comment at this line out and we're gonna make this just a kind of a make script not a run script And so I'm gonna actually rename that Make that SH we also have the actual code. So what's in the code? You can see here. It's The entire useful part of the function of the program is just return zero So if we make this and then run this binary We should get an output of zero which we do okay, so Let's now implement this piece of software if you can call it that So first things first I mentioned that this print routine was not buffered So we'll get rid of everything to do with print buffers. This will save us in this case four kilobytes of memory when the program is running You can see here the OS is clearly generating a Chunk of memory that is this size for us so we can shrink that down by 4k We'll do that and we'll clear out this print buffer because we're not gonna use it Okay, so how will all our includes be well, let's grab those so we said where there was an include from lib math Rand Rand int Said there was an include from Lib IO parse int and There was an include from the bio Print ask And of course there's inputs and outputs. I'm not gonna put them here if you want to see them Just rewind the video or check the sympositor. Okay So what's our logic going to be? so first thing is going to be grab and parse input number from the command line And we're gonna have a loop In that loop we're going to Generate a random character We're going to print Random character And then we're going to loop until done And then we're going to exit That's the full logic for this very sophisticated pieces of software So how do we grab user input if you recall? I believe from episode 3 we Did this and the way that works was essentially we have a pointer and it varies on Linux or spsd That's why it's included in that syscall listing at the top there the Let me get so I don't make a mistake in typing the Location of that Character array is sort on the stack. It's the address of the first Part of that array is on the stack and so that's actually located at Sys argc start pointer. That's what we're calling it at least I think on Linux. That's the stack pointer and then on BSD. That's actually I think RDI And so that's why we have a kind of a variable here that can be either one of those two options And so the way this works is we're going to move that into RDI now this pointer Points to argc. That's the number of numbers were passing number of arguments were passing in now if you wanted to be really smart It's so we have to check the number make sure it's make sure it's two And if it's not two points an error message in yadda yadda yadda yadda I don't has to be a number it can't be a string blah blah blah. No, sorry That's not how I operate. I don't typically Use my own software incorrectly. Maybe you do in which case puts an error handling in not me though So this points to argc. I believe plus eight that point would point to the actual Program name. It's the first bite of that string and then 16 would point to the second String which is our input. So this would point to like two eight Zero in our case that would be 28 and then the null bite So yeah, that's how this one works and now we're just gonna move that into you parse it and so we're gonna call parse int and this will put the input number in Rx actually, I'll say integer because that makes it more official and then typically so we're gonna loop through this rx times Typically You use RCX as the loop counter and so we're gonna put that in RCX And loop through RCX So that's down here. So our loop is going to basically document RCX each time and then while it's not zero We're going to jump to the top of the loop and now probably we should check for negative numbers because Potentially you could pass in a negative number or zero. So let's do that. Let's really quickly compare Either RCX or RX with zero and we will jump less than to exit Less than or equal to and I'll put another label down here That means if we pass in like negative five or negative a hundred or zero It won't loop forever. Otherwise this loop will go forever. Of course. We could put a well Yeah, the thing is if you pass in zero and you put like a jump Greater than zero down here that would work But it would also be incorrect because it would still run once if you pass the number zero So this is probably the safest way to do it. Just check if your input Is zero or less in which case just leave the program Okay, so how do we take a random number that uses that random number a random int? function and this will put the random Value in Rx and of course we pass in the balance, right? So we're going to move into RDI What are the bounds? Let's see have an asking table right here the valid bounds for Password type letters would be a guess exclamation point or decimal 33 all the way to perhaps the tilde Which is 126 that would include all the symbols of a lowercase uppercase letters and also the numbers so 33 and 126 so we'll say 33 Move RSI 126 call random Great, not the character So we're just going to move into RDI the output file descriptor so sys standard out we're going to move into RSI The value in Rx, of course it's going to be within a byte so we can use the one byte numbers here We'll say AL and SIL and then we say print ASCII Now this as this written should work I will do one more thing really quick to make it easier to see the output and that is I will print a new line character down here so I'll print out a single ASCII new line character down here. What is the ASCII value for new line? Let's check for the quick. I believe it's either 10 or 13 10 yeah line feed new line So we will pass in 10 into SIL Now I'll print out a new line and this should just work the program is basically done I think If you want to add air handling be my guest let's see if it works. So if I close out of this I run that make script Oh, let's see. What did I do wrong here? Okay, I didn't it should say call print ASCII. Okay, there we go Let's Run that Again, what have I done this time? Oh the same thing copy and paste geez all right That's probably should have been obvious to me Make now we have our binary. How big is the binary to see really quick? The binary is 408 bytes. So let's now run this binary with an input. Let's say eight is That eight characters long BZ 2x semicolon plus ZQ Yes, eight characters. How about 12? Looks like 12 to me. How about 16? How about 16,000 Looks good to me. How about a binary number zero B? One zero zero zero should be eight Looks like eight to me. How about a hex number? Zero X one zero. That's 16, right? Looks like 16 to me. How about an octal number? I'll be that's Is it zero? Oh, what I do for that? Seven seven Yeah, I don't know maybe probably 64 that what I'm not sure what that is Yeah, so I mean it works right and it's only four hundred and eight bytes Can we improve this? Should we check? Yes, we could here's one way to do it so this stated out I know for a fact that is like a either a one or something like that. So you can make that a DIL You might be able to Shrink these down, I would I don't want to risk it, but you probably shrink those down if you wanted to You could skip this X or if you don't care about the return value of the function I believe that though. What does that make the program now? It is 404 bytes, so I don't know you couldn't get I mean a Python interpreter is how many megabytes or whatever hundreds of megabytes probably Not gonna happen, you know Matlab bash, you're not you're never gonna beat this byte count and Even the fact that we're using a syscall per character, you know type in binary eight. This is gonna be ten syscalls Even still I would bet that it's probably For small strings like this. It's probably still faster than These scripting languages if I had to guess of course if you type in, you know eight million or something Yeah, maybe it would have become a little bit slower because you can't run eight million syscalls and expect your program to be fast But you know for these smaller programs smaller strings. I think it's fine So yeah, anyway, that's the video. I just want to show that you could make these efficient pieces of code small easy quickly things that you might want to do in Python or in bash or in some kind of web Development language you could do it in pretty much the same amount of effort or similar effort in assembly at least for me So yeah, thanks for watching. I'll see you in the next video