Reverse Engineering 101 tutorial with the amazing Stephen Sims!

David Bombal · Beginner ·🔐 Cybersecurity ·1y ago

Key Takeaways

This video tutorial covers the basics of reverse engineering, including compiling and running C programs, using GDB for debugging, and understanding memory, signals, and computer speeds. It also delves into shared libraries, dynamic linking, and buffer overflows, providing a comprehensive introduction to reverse engineering and cybersecurity concepts. The tutorial utilizes tools such as GCC, GDB, and ELF executable and linking format, and touches on topics like procedure linkage tables, global o

Full Transcript

cuz this is what I tell students when I teach classes uh is let's start out with Hello World everybody's favorite application of course very very simple program that just prints out to the screen hello world and then we'll expand upon that so here we're just jumping in and we're going to say print F and then hello world very simple this is the most basic that you can do so let's get out of here so we'll say GCC minus o hello world and hello world C so it's going to produce this program called hello world now so if you look in the direct Factory you can see we have hello world. C my source code we're going to run GDB and I'm going to say minus- NX so let's say the program name hello world and you can see down at the bottom here it says no debugging symbols found in hello world so if you compile the program to generate debugging symbols on on Windows be call these pdb files those are the debugging symbols symbol is a fancy way to say function names and you know function prototype data might be there and and other the names that very Ables like usually the program doesn't need that data it makes it a lot easier for us to reverse engineer things I want to thank brillian for sponsoring this video do you know how technology works as an example how strong passwords work how wireless communication Works how computer memory Works brilliant have courses that cover a whole range of topics including computer science and programming so as an example computer speeds today are measured in billions of operations per second but data needs to be stored somewhere so we need to store data in memory but do you actually know how memory works and that's what this course teaches you we take this for granted today but improvements and memory are one part of why video game Graphics are so much more detailed today notice 1 kilobyte versus 1,000 kilobytes of memory now in this course brilliant takes you on a journey and it's very interactive training so as an example we told that signals are carried by wires notice as an example here we can set values on the left and then write that to our memory cell now transistor controls whether the signal is carried Through the Wire to the capacitor however which input is the data and which controls whether the data is written so notice as an example here I could set this to one and notice B writes the data input B is right input a is data gives you a basic introduction to memory and then goes more complex explaining memory cells and how they built with capacitors and transistors now I really believe that education changes lives really want to thank brilliant for creting training material like this but also supporting my channel use my link below to get a special discount hey everyone it's David Bumble back with the amazing Steph Sims step great to have you back on the channel yeah great to be back it's been a while yeah it's been too long just for people who don't know Stephen Steph's the author well one of the authors of this book but Stephen you've been teaching at sanss for a long time and I believe you've been hacking for over 20 years is that right yeah my my joke is I don't know how that's possible since I'm only 30 but um yeah 20 long time now I love that so just for everyone who's watching I really like to emphasize this Steven you've got a channel that's been growing really well so I'm glad to see that but people who watch my videos often complain that the content that I have on my channel is too simple you know it doesn't go into like hacking programs reverse engineering and other hardcore topics so for everyone watching please go and sub to Steven's Channel because he has a lot of live streams where he goes into great depth and if you really want hardcore technical content go to his Channel and sub so please go and show the love Stephen you've been expanding into many topics right so it's not just hardcore stuff you also do like a whole range right yeah I've been having a lot more guests lately uh it's it's been working out really well where just amazing people from champy if you P her and yarden shaffir over to Pavo yosifovich and kubba Gretzky I mean amazing people I've been very fortunate in that way and um I've been doing solo streams as well still but yeah it's kind of going Beyond just reversing and exploit development and covering other things to like Cloud Ai and other topics so just again for everyone watching please go show the love go and sub but Stephen today's video is I'm really excited about this it's not something that I could say that I know a lot about but you've been doing this for a long time and that's reverse engineering correct yeah I figured uh this being the first one and we can do another one later but uh this one cover basic reversing on both Linux and windows that's brilliant so I'm going to hand it over to you I'm going to try and keep quiet because a lot of people complain if I interrupt you so teach us so yeah this is just a auntu VM and I figure we'll start out by the very basic just because this is what I tell students when I teach classes uh is let's start out with Hello World everybody's favorite application of course very very simple program that just prints out to the screen hello world and then we'll expand upon that but the idea is to show you what it looks like on the disassembly side so you can kind of start getting used to what things look like in the assembly syntaxes that you can use and just some basic things that always tend to be there that once you get used to seeing them it you can just like ignore them like oh I know what that is I know what that is and you can skip over things and a lot of people when they first go to reverse engineer something it's it's can be intimidating especially if you're using a disassembler like gidra or Ida Pro or or Binga and you open up a program inside of it and you just get this massive amounts of disassembled blocks and it's you know it can be intimidating first so it it just really takes a lot of practice once you do this over and over again like with anything I mean how many people do you know who said I want to learn Japanese it's a great language and as adults how many of us actually follow through and do that so this does require that level of um attention and and detailing you know for me I had to give up things over the years that I like gaming get to do much gaming these days because when you have a family and all of that you really uh need to prioritize your time so let's just uh go right in I think the first thing we'll do is the hello world examples so let me just um create a program here we'll call it touch hello real. C let's just go in so one of the things and I don't want to get too much into the C programming language like Basics that's something that would be another stream that we could do there there's a great resource that a friend and instructor author of mine at the Sans Institute created his name's Jonathan Ryder and he created this basically introduction to C programming series and I believe it's eight or nine 2hour workshops and they're all up there we can post a link they're all up there on the site on the sand site and they're free and all the tools everything you need is there and that's a really great primer into learning C and I know a lot of people are like well why don't I care why don't I learn about rust or or Python and obviously those are great languages but so many of big applications and operating systems are in C C++ Objective C or straight assembly so it's really important to know those languages especially if you're going to be reverse engineering uh big applications and doing things like malware analysis or vulnerability research so one of the ways programs work is when we write a program we create our own functions that are internal to the program but we also like to leverage existing functionality in shared objects or libraries so that we don't have to rewrite all this code so if want to print something to the screen I don't have to write my own function to do it I can load a module and then call the function print f for example and one of the things you have to do is import the libraries or modules and when you actually run a program part of the create process functionality is actually going to map on Linux we mmap those shared objects into the process address space so that we can then go and Link it and utilize that functionality so linking is the process of when let's say I write a program and you are running it on your computer and I'm depending my program has dependencies on some functionality that I know that you have on your system because it's part of libc if I L the generic libc libraries and so when you run my program it has to be able to load those modules from your file system which are the libraries and then we actually need to link the functionality which which means how do I know address the function my program needs to call is at and that's a linking process so you probably heard of statically compiling a program versus dynamically linking one statically compiling one means that you are compiling all of the libraries into the application that's produced once you compile it and that means it doesn't have any dependencies really because they're all statically built into the program which makes it unnecessarily large and it also makes it vulnerable to the fact that if there's a vulnerability discovered in one of those libraries that have been compiled statically into your program then that program anytime anybody runs it is going to be vulnerable that's one of the benefits of dynamically linking something is that I'm going to load the latest version of those libraries and if you patch things up to date then we don't have to worry about vulnerabilities as much is is that like dlls on Windows yeah exactly dlls on Windows shared objects on on Linux so I'll probably drop some more kind of random bits and pieces of that stuff as we cover things because yeah it's it's important all right so let me get started here so I'm just going to put a couple of modules in that I know we're going to need so let me put those two in we're going to say uh include over at standard IO in the header file and then we're also going to put in string.h because I'm going to need both of those in the examples we're going to be doing here next up I'm just going to create a main function which is the first function that executes once the program gets loaded and ready to go one of the first things you do is a fun function declaration and you probably seen things like int main or something like void main now what that means is if you're expecting something to be returned back from the function to the caller then you need to specify that by saying void that means we're not expecting main to return anything back but by saying it then we might return back a status code like a zero if everything is okay or one if things aren't okay so sometimes it doesn't matter what you put here but I'm just going to leave it void for now and we're not some a lot of times you'll also see something like int Arc Char star arv which is the argument Vector we'll get back to that I'm not going to use it in this first example so here we're just jumping in and we're going to say print F and then hello world very simple go to do it yeah got to did it and it we'll close that out so the sln of course means new line and then I didn't use a semicolon so that's why I did that and then what we're going to do now is simply say return actually I don't need to put a return because we're leaving at void right so I'll just close it out this is the most basic that you can do so let's get out of here and then now we'll go ahead and compile it so we'll say GCC which is the G new compiler now one of the things is that you need to know about compilers is that by default there's a lot of exploit mitigation that get compiled into the binary automatically like you don't have to do anything if you don't want those mitigations to be compiled in you have to specify that there are mitigations like Pi which is position independent executable and that actually uh randomizes the load address of the binary itself and then there's you know aslr ad space layout randomization on the system in general which randomizes the stack memory and the heat memory and other things the libraries uh the other mitigations like NX which is going to be dep data execution prevention stack canaries like all these mitigations that are there to protect our program in case we accidentally have a vulnerability in it right so mitigations are what protects us when the root cause is that there's a vulnerability in your code so we'll say GCC minus o hello world and hello world C so it's going to produce this program called hello world now so if you look in the directory you can see we have hello world. C in my source code and then we've got hello world the binary itself now I might turn off Pi position independent executable just so we don't have randomization to deal with in the binary normally in the debugger we can turn this stuff off anyway so let's just take a look and and see what happens here so we're going to run GDB and I'm going to say minus minus NX that means no extensions because right now I probably have an extension like Jeff or Peta which is the python exploit development assistant these are basically little Frameworks or extensions that Aid Us in things like exploit development but they a bunch of context and noise to be on the screen so I think it's easier just to disable that for right now so let's say the program name hello world and you can see down at the bottom here it says no debugging symbols found in hello world so if you compile the program to generate debugging symbols on on Windows we call these pdb files those are the debugging symbols symbol is a fancy way to say function names and you know function prototype data might be there and and other the names of variables like like usually the program doesn't need that data it makes it a lot easier for us to reverse engineer things some of it's automatically there by default and we need to strip it out as a developer if we don't want people to see the internal function names but one thing you cannot strip are the dependencies and I'll show you how to look at those here in just a moment right now we're in GDB I'm going to go ahead and clear the screen so we have it nice and clean and I want to say info functions so what this shows us are all the dynamic dependencies as well as the internal functions so as you recall I only created one function and it's called M which I've highlighted there some of these other things those are just part of the object file format which is eelf executable and linking format that's the binary object file format for Linux eelf executable and linking format on Windows it's position or sorry portable executable common object file format so PE cop but we're going to focus on elf right now so some of these things are just part of the built-in stuff that goes inside the program and then others as you see up here I said print F right I I said use print F and look what it did it changed it to puts so compilers will make decisions on your behalf sometimes sometimes the it'll even try and remove a a vulnerable function like stir copy and change it to St end copy for you depending on what compiler options you use so if you want to force the compiler to do things and not make changes on your behalf you need to turn off things like optimizations and other things that can help with that but right now I'm okay with it being puts because puts just puts a string onto the streen just like print F would do but one thing you might notice is it says at PLT after word that means procedure linkage table so the procedure linkage table is part of the linking function ity on Linux there's something called the procedure linkage table and the global offset table those two things together are what's responsible for linking a function that my program depends on your system having so like I said earlier if I don't statically compile and I didn't hear I expect you on your system to have the library code to have print F or puts in this case and if you have that we link it so that's what you see PLT for procedure linkage table what actually happens from a high level is when you go to call that function for the first time it calls into the procedure linkage table for every function that we have a dependency on it gets an entry inside the procedure linkage table so for example and I can show you this in a little bit puts entry will then have a jump instruction to a pointer inside of its relative entry in the global offset table and the first time you go to link something it may not actually be linked and that means the dynamic Linker has has to go resolve that symbol and get the address so a lot of information there let's step through some of this as we go forward but one of the first things you typically want to do when you're reversing a program is looking at what functions are both internal and our dependencies and if this program is stripped you wouldn't see a lot of that internal functionality let me show you what I mean real quick so I'm going to drop at it here and I'm going to copy hello world and call it hello world 2 if I say file on hello world see how it says not stripped right there watch what happens when we do it on Hello World 2 it's not stripped but wait strip hello world 2 and now if we run that you can see it says stripped instead of not stripped what does that mean well like I just showed you if you take one more quick look here GDB NX hello world and I say info functions that's what we just saw before right all of this and you can see the main functions there if we drop out now and now we look at hello world 2 and we say info functions see how there's nothing there except for those two entries so that's going to make it harder for you to reverse engineer a program because now we don't have those function names unless we've got the debugging symbols and those function names are typically really useful because it's the name of what the function does like if you see a function called calculator you can assume those calculations Let's uh go back to the other one that is not stripped all right so now that we know what functions are inside we know there's one called main so let's say disassemble and you can tab complete with these commands inside G debugger and we'll say made so what we see right here is a very small function and there's a couple things going on so this very first instruction actually these first two instructions that's something called the procedure prologue that that is the code that's inserted by the compiler based on the calling convention you select that sets up a stack frame and then at the bottom it tears down the stack frame so a stack frame is a little allocation of memory that every single function gets when it's called so it's used for things like taking an arguments maybe having a buffer so something gets stored there temporarily but it's a finite operation because functions are finite right you get in you get out so it's great that the compiler inserts code that automatically sets up this stack frame and then tears it down when the function's done one of the very first things that happens when you call a function is that a return pointer gets pushed onto the stack so that when you hit this return instruction at the end it returns back to the collar where it left off and I'm sure you've heard of buffer overflows and people wanting to get a hold of that return pointer because then they're able to hijack the uh code execution just for everyone who's watching we we did a video together Steph and I'll link that below where you showed like exactly that in a buff overflow that's right good call so that return Q means quad word that means we're looking at a 64-bit program instead of a 32-bit program okay so here's the important stuff though right like this right here is the prologue this right here is the epilogue this knop is just there probably for spacing um it's a no operation instruction it doesn't actually do anything when you execute it it just advances to the next instruction right here is the meat of this function all it's supposed to do is print to the screen so you can see this call quadw puts at PLT that's the function that's actually going to print the data to the screen but how does it know what to print well this right here is the argument that's being set up and passed to the call instruction so what we're essentially doing it and one thing to point out here if you're looking at this and you're like why does it look really weird exactly because it's AT&T syntax this is not Intel syntax right now because by default GDB uses AT&T it actually threw me off right now because I'm like wait why are we moving what's an RDI to the instruction pointer offset like that didn't make sense I was like oh yeah it's 18t so I'm actually going to switch it over to Intel because that's what 99.9% of people use and that's what pretty much all disassemblers on Linux and windows default to so to do that we just say set disassembly flavor Intel now look at the difference when we disassemble that function see how this instruction here now looks like this see how it kind of reversed things this right here was at the beginning but now it's on the back so it's a good time to point this out when you were disassembling you were basically taking the op codes which are the instructions for the computer to execute the op codes itself and you're disassembling them into its pneumonic representation that's what we're looking at here is the pneumonic representation that's the disassembled op codes now the flavor is whether or not you want to view it in Intel syntax or AT&T syntax like I said Intel is pretty much the default for everyone but it's a preference and let me show you how to see the actual op codes as well because this will help make a little bit more SS if I say disassemble SLR main see how now we have these weird hexad values in the front those are the op codes and GDB doesn't display them by default because it makes the screen kind of ugly here right up here it's nice and formatted down here it's all kind of in you know offset so by saying SLR you're saying I would like to see the op codes as well one thing you can notice is that some instructions are only one bytes one bite and then the next one is a three bite instruction the next one's longer than that right here are the offsets from the beginning of the function so since the first instruction is only one bite that's why we go to offset one after that and that's why we go to offset four because the second instruction is three bytes but my point between the flavers is that if we go back here and we change it to AT&T and we run that command again see how the off codes are exactly the same regardless of the syntax it's the way in which it displays the disassembly to you that changes so it has nothing to do with the op codes because that's already the compiled code assembled code it's the way in which you wish to view it and I'm going to go back to Intel because that's again the preferred option and let me explain to you how to read it though so in AT&T syntax you have the instruction followed by the operand sometimes there's no operands it's just an instruction like n that's just a single bite instruction with no operands this example here with push is an instruction that has a one by operand or has one operand I should say not one bite but one operand sometimes things have two operands like look at this one move RSP comma RBP now here's the important thing I'm pointing out at AT&T and Intel one of the main differences between the two is that the operands are swapped position wise so this is AT&T that we're looking at right now it's with highlighted this says move this into that so move Source into destination if we run that same same disassembly in Intel it's reversed move into this that so it swaps the source and destination if you can read one you can read both you just got to remember the little differences between the two another difference is that in AT&T you see this percent sign there and down in Intel there is no percent sign percent sign in AT&T means indirect operand it means what's stored in here so this instruction says move or actually copy the contents of this register into that register so it's not a cut and paste it's a copy paste so now both of those registers would have the same thing in Intel we're saying move into this register the contents of that register again copy paste source and destination or swapped sometimes op operands have a operand value like this example down here it says rip which is the instruction pointer plus this offset so that's the operand value so pick one stick with it I would recommend me Intel because a lot of tools don't have the option to switch between Intel and AT&T and you're pretty much stuck with that one and that's the one that people seem to enjoy more so let's drop the op codes and let's take a look again me clear the screen is it just historical that they two versions or was it like some history they will is it irrelevant yeah yeah great question um question is of course is it historical like what's the reason behind the two syntaxes there is a lot of uh weird things going on back in the day like in the 80s and the 90s and there were like Intel and IBM and other players who could there was patents in place and other things that required things like little Indian and big Indian to be a thing where that's the position in which things are stored in memory either either normal way or in Reverse way Little India uh similar thing here Intel and AT&T these companies had their own preferences in the way in which they did things and there was Forks of those things so there's a lot of interesting history lessons that happen back into so back here again one more time we've got the address over on the left this is the virtual memory address of the start of this function this is the offset from the beginning of the function we saw that some instructions are multiple bytes some are single bytes and then we see the instruction followed by the operand or operands and also sometimes the operand value so that's kind of the the layout you need to get used to again these offsets are important uh one of the reasons why these offsets are important if you ever heard of something called return oriented programming in x86 architecture the instructions are variable light meaning like you saw there are one B two by three bite all the way up to maybe 15 by instructions as where on another architecture like arm their every instruction is four bytes unless it's a thumb instruction then it's two bytes so every single instruction is four bytes that means that things like return oriented programming is going to be easier on x86 architecture because we can actually index into any offset within an an existing instruction and if we can get control of the instruction pointer and redirect the flow of execution we can tell it to go in the middle of an existing instruction and it will interpret those bytes as completely different op codes so it's a really cool thing that you can sometimes do all right so this back to here the argument that's being passed to the puts instruction all we want to do is print to the screen right puts needs to know what you wanted to print to the screen this instruction here says load the effective address into RDI whatever is stored at the instruction pointer plus this offset so basically an address is going to get loaded into this register and then the puts function is going to use that register as its argument so it knows what to print out and a cool thing that we can do is we can actually issue a command to look to see what's at that location so if we set the break point right here so I'm going to say let's break at pointer main plus the offset which is going to be four what this is doing is I'm saying asterisk because I'm saying pointer if you give it a function name you can do that but since I want to go to offset I've got to tell it what that is so I'm saying main plus offset 4 which means it'll break or pause execution when we hit this instruction so I've set that break point now and now if we say run you can see we hit the break point right away so we are at that location now another thing to notice look at the address here 1139 and look at the address here what happened I didn't compile it as a position independent executable so things are being randomized so each time you run this Pro this program the address the location is going to be randomized to make things less predictable for an attacker so that's what you're seeing there if I want to see the instruction where we're at right now I can say x for examine /i the instruction at the instruction pointer rip does not mean rest in peace it's the 64-bit instruction pointer when you see an r on the front you know it's a 64-bit x86 instruction because R stands for register and then the name of the register uh on 32-bit you would see EIP which is extended instruction pointer and then in the old days on 16bit architecture you would just see IP and that's the program counter so right now I'm saying show me what instruction is at the instruction pointer right now since we paused execution and you can see we're exactly where we want to be so what I want to know now is what is stored at this location because that should show me what puts is going to print to the screen so I'm going to say XS that means examine memory as a string and then I need to pass it a memory address so it knows what to print out so I'm going to say dollar sign rip plus that offset 0x ec4 and it's empty which is interesting I don't know why it's showing me that being the case RF plus 0x ec4 so what this should do is actually dreference this location into the RDI register so it might be a pointer to a pointer there might be some other things let me look at the instruction at that location XI add by pointer no it doesn't seem to be an instruction so let's um go ahead and step one instruction and let the address get loaded here now you can see over on the right this address here and when we did it it did not print out that location so if we take that address and we say XS 0x 55555555 604 it says hello world so that's the address of the string for hello world is getting loaded into RDI so then that'll get passed to the puts instruction so it prints it out to the screen so that's essentially What's um happening let's look at the RDI register right now because we haven't let this instruction execute yet if we say info regge RDI that's what's stored there now is just literally one if I say si for step one instruction that'll set with something called the Trap flag and the flags register and break immediately at the next instruction or address and now if we look at RDI you can see it's got an address so it changed from being one to this address because that's what got loaded it got dereferenced into dreference means go to the address that we're pointing to take what's stored there and load that into a register in this example so now this if you look where we are in the program we are on the call to the puts in um function so puts is going to take RDI which is the stores the address of the string as its argument so it knows what to print out now notice that it says call puts it PLT it's not going directly to the puts function like you would think it does you would think okay we're calling the puts function we're going straight to it that's not how it works when you dynamically link things remember I explained that earlier there's something called the procedural linkage table and the global offset table so if I say si for step into step one instruction we are now in puts entry in the PLT so let's look and see what instructions there it says jump to the qword or quadw pointer again that 64-bit pointer at this location where that jump is going or where it's pointing to is the global offet table entry for the puts function so one more time any function that we need to dynamically link like puts or stir copy in order to call it it has to be linked and every function that we depend on gets its own entry in these little tables called the procedure linkage table and the global offset table so so what's happened here is in the main function we're calling puts at PLT we are now in the procedure linkage table entry for puts which says jump to the pointer stored at this location at that location is the global offet table entry for the puts function but the thing is the very first time it's called it hasn't been linked unless you turn a mitigation called relocation read only on since it hasn't been linked it'll be an indicator that says what is stored at the pointer is not the puts function you need to link it something called the dynamic Linker takes the symbol name and it looks it up and then resolves it it writes the real address of the puts function into the global offset table so we only have to link once per process invocation so if we want to see what's stored there let me see if it'll let me do this examine and I'll say GX GX means giant which is a quad word which is a 64-bit integer or variable uh X means as hexadecimal so I know these commands can get kind of um you know if you don't know them you don't know them and there's a lot of really good GDB cheat sheets out there that will help you this is one of the reasons why a lot of people love gooey debuggers because you don't have to worry as much about these commands with some of them unless you're using one like wind debugger wind dbg that one is is a amazing debugger and disassembler but it's got a lot of you know commands that you need to learn look with anything so I'm going to say rip plus ZX 2 f9a so that's what's stored there what's going on here is I'm not since this is a pointer it's saying jump to the quad word pointer stored at this location plus this offset so I'm not executing the right command to go and actually dreference that you can do that by um introducing like asterisks and things like that and the different command syntax like asterisk and then parentheses Char space star star Stu like that like actually go and dreference things but what I'm just going to do to make it simp easier is we are going to run a command from here against a shell so I'm going to say shell what that does it says you know basically get out of the debugger for one command and do something for me I'm going to say run the command obj dump minus capital r which means relocation and then the program name which is hello world what that just did is dumped out the global offet table so remember I said the procedure linkage table references the global offset table and we could see that the entry for the global offset table for puts is right there at 3fd Z again this is not a position independent executable or it is I mean if I turn that off it'll be a little bit more static all right let's go back here so what we've done so far is we saw the procedure prologue this sets up the stack frame at the bottom it tears down the stack frame we watched an argument which is a pointer to a string it loaded into the RDI register and then we call the puts function passing the address of the string hello world for it to print out this is a obviously a very very basic program now let me drop out of here real quick and let's see if I can recompile this and let me try to say no Pi so minus no- Pi that should turn off the mitigation and look at the difference now if we go in and we say disassemble main see how the address is a bit longer now before it was only like three bytes think and now it's a bit longer that's because we're telling it not to randomize the program itself and we should see something a little bit different if I break on this instruction where we call puts I'm going to say break main plus 11 run and now we're at the breakpoint so we're going to call puts now if we step into it you can see now we are just like before at puts entry in the procedure linkage table let's look at the instruction there again so examine the instruction and now it says jump to the quab pointer pointer 2f2 from rip so since aslr is not on now if not a pi now I'm wondering if my command will work more easily so we're going to say xgx dollar sign rip plus 0x 2f E2 uh we're we're close 40418 but that's going to show us if we look at this Lo loation so if we say examine 0x 40418 this is what's stored there right now look at that address and how close it is to the address where we're currently executing code it's only six byes further away that what's happening there is because we haven't linked it yet that is telling the dynamic Linker you need to go resolve this function and to demonstrate that to you if I Say ni for next instruction what that means is step over the next instruction and we should be able to see puts get linked so let's take a look here or we're still on the PLT so it's just running code associated with the dynamic Linker let me go ahead and check that location now so see how now when I check that location remember what it was before it was a pointer straight back into the procedure linkage table right by where we were and now it's got this address now it's been linked so if we take that address now and we say x8i which means examine eight instructions 0x 00007 f f ff7 e51 cc0 you can see we are actually inside the puts function now so it got linked I know it's not the prettiest thing to look at but it is kind of interesting what you just saw is you saw a function that we depend on get Linked In runtime and you saw that when it would to call that function the first time it hadn't been linked yet and we just let it link and now you can see the real address is written to that location which is nice all right so let's drop out of here because I know that that's not the most exciting one to look at but I wanted to start there just to show you some Basics so that now when we add a little bit more to this C program you'll see some changes and you'll like oh now I see the Delta I see that new things have been added so I'm going to open up the program again so we'll say viello world. C so that's what it was before pretty simple right not a lot going on there what we can do we can do one of a couple things we can take in an argument and and let the program print what you type in or we can also take what the user types in and we can pass it to a function that actually prints it out to the screen and I'm going to go that path because I'm going to introduce a little vulnerability into the program just so you can see how it all looks and one of the first things I'm going to show you once we compile it is how we can exam the argument vector and I'll show you exactly what that is so let me go ahead and um create a new function here I want to say int we're going to call it um fake print f is what I'll call it and then we're saying int because we're going to expect this thing to return something back to the caller but I'm going to say now Char star AR what this is going to do is um take in an argument a pointer to the argument it's it's a character and we're going to take an a pointer to it so that we can then print it out to the screen with this function instead of the main function so let's go ahead and put the code in for this going to create a little buffer and we're calling it name it's a character buffer we're going to use the the bad command stir copy that you shouldn't use and we're going to copy into that buffer of 16 bytes with the user of the program passes it so I'm going to call it AR which we just pass the pointer in and then we're going to say whatever that person printed in we're going to print out from the buffer so print F hello and then percent s that is a format string for telling it basically print out what is passed as a string if we change it to D prints as an integer if we say F it's a float so we have a bunch of options here I'm saying s because I want it to be a string followed by a new line and then take in name if all goes well Return To Zero all right so that function is done now now we're going to go on to main we and change this to int and in here we are going to say int AR C that's the argument counter Char star argv which is the argument Vector I'll explain those in a moment here I mentioned it briefly already but we'll talk about it again okay next up we're going to say if ARG C that's the argument counter is greater than one so what this is going to do is say that if the user enters something in I want to call that fake print F function if the user doesn't enter anything in it's going to default the printing hello world so that's what we're going to start doing here all right so now now I'm going to say call fake tra F take in ARG V offset one now this is an important one to understand so the argument Vector the argument counter is just a counter the argument Vector though it's basically an array of the arguments the first offset is always going to be the program name so rv0 index offset zero is always the program name itself and if you say ping and you don't enter anything argv Zer is Ping if you say ping space 1271 arv1 is going to be that IP address you passed in so we have to handle the arguments because if we're taking in more than one argument we've got to know how to you know sort them and such so I'm saying if the user entered in an argument what we want to have happen is call the fake print F functions and then um pass in the argument and then we're just going to return zero great so we've got that and we're going to close out that if statement and and then otherwise else print of hello world and then return zero then then close it out okay that should be the whole program again not very exciting but a little bit more complex than our last one so basically what's going to happen is if we run the program and we don't pass in an argument it's going to print hello world if we run the program and we pass in an argument it's going to take that argument pass it to this function up here which takes in a pointer it we have a create a little buffer here the argument is going to get copied into that buffer that has 16 bytes and that it's going to print out that that uh but what's in the contents of the buffer to the screen that's all it's doing um the problem is Stir copy and the fact that if we enter more than 16 bytes it's going to overrun the stack and cause problems so let's go ahead and quit and now we're going to go and compile it again all right no errors it's always good be sad if I had an error in such as simple program but let's go in hello world now remember what it looked like before and now it's going to be a lot more complex well a lot is relative but compared to the last one so I say disassemble main see it's much larger now right before it was only a few lines so the the first interesting thing that's happened here and this one I want to explain first is that after this procedure prologue remember I said that that little instructions there gets inserted by the compiler and it sets up the stack frame and we still have the tear down of the stack frame down here before all we had was a call to puts right and the argument being passed to it so that code from the last time is right there and that's that's all it was and now we've got this right here which is basically returning that argument because the accumulator register is what returns back an argument from a caller like a status code or something else and then we've got this code up here like what's going on up here this is basically checking the argument Vector to see if we entered something in or not so the first thing I'm going to do is I'm going to change the disassembly flavor so Seth disassembly flavor to Intel and then dis assemble Main and right here see this comparison it says compare double word pointer whatever is at stored at the pointer at RBP minus 4 against one so remember we put a condition in the program that said if the user enters in an argument we're calling that fake print F function if they don't then we're just going to print hello world so the condition is being checked right here it says jump if less than or equal so if the number of arguments is less than or equal to one and remember there's always one argument which is the program name itself so if we don't enter any additional arguments just a program name we're going to say JUMP if less n or equal to this location which is down here that's going to then call puts and print L world if we're not less than or equal so if the user enters more than just a program name then we're going to go call this fake CRF function and pass that to the buffer or cop it into the buffer and all that so let's run the program first actually I'll set a breakpoint here this will be a good spot so main plus 15 so break main plus 15 and we'll say run I'm not entering in any arguments right now we're at the instruction and you can see it says compare the double word pointer RBP minus 4 to one so let's see what's at that location here so xgx at RBP minus four that is not it's a pointer stored there great so again we're at the point where we are comparing the pointer at RBP minus 4 against one and one is going to be if we only enter in the program name if we enter in the program name plus any arguments then that comparison should fail like we saw with the jump if BL Center equal instruction of to go let's go ahead and check to see what's at that location so I'm just going to say x SL BX BX means check just a single bite because all I care about is one bite at the end of what's stored at that memory location and then we're going to say dollar sign RBP minus 4 and you can see what's there is a one so essentially what we're doing is comparing a one to a one so that next instruction if we take a look at it says jump if less than equal well were we less than or equal if we compare one to one yeah we're we're equal that means we're going to take the jump so if I say si to step instruction we're going to go to this address right here and see how we're there now and at this location if we say x SL 2i we are going to call puts and print out hello world like we saw before now let's see what happens when we enter an argument so I going to say run and this time monkey so we start the program over and we hit the break point not EIP me rip so we are at that comparison again let's see what's stored at the spot now see how it's a two now it's a two because we added an argument if we added a third argument this would be three and this comparison now if we say step instruction we take a look where we're at we are not less than or equal to what so we're not going to take the jump so instead of going to this address like we did last time if I say step instruction see how we went to the very next address after this one and now let's take a look at the instructions x4i instructions RP so this is moving some things around and anytime you don't know what an instruction is just look it up that's what we all do and then once you get used to seeing it a bunch you remember what it does what all this one is doing is moving into the Rax register that's the 64-bit accumulator register what stored at the pointer at RBP minus hex1 Z and then you can see we're adding eight bytes to what's stored in R ax and then we're taking what's stored at that location and dereferencing it into Rax and then we're moving Rax into RDI and if we look at some additional instructions here after that we're calling fake print F so all this is doing right there is taking the pointer to to the string that we entered in and it's passing that address to the fake print up function that's all that code is doing because think about that if we are not if we didn't get that comparison and we're not just going to default print hello world the function supposed to take in our argument and print to the screen so we're calling a function to do that we need to pass a pointer to the string that the user passed in that's all that's going on there and then so let's go ahead and go into the fake printf function so we'll say uh step instruction let's just keep going until we get down to that call all right now we're at the call so I'll say step into and now you can see we're inside the fake print F function so let's disassemble now what's happening here there's the procedure prologue again that's setting up the stack frame for the called function this subtraction going on there this is subtracting hex3 0 from the stack point that's allocating a buffer because remember we're going to be copying the data that we we typed we entered in which was monkey and we're going to be copying that into the buffer using a stir copy function this right here is likely setting up the stack Canary um I'm not 100% but that's potentially doing that let's see what's at the end of this function yeah so see right here where it's xoring what's stored in rcx against this location that's where the if you've ever heard of Stack canaries or stack cookies that's what's going on there at the beginning up here it's setting it up and it's writing it onto the stack so FS is a segment register and it's taking the stored Canary that was created during this process and it's writing it onto the stack and it's protecting the buffer and at the end before we're allowed to return control to the collar it's checking to make sure that we didn't uh corrupt that that Canary so pretty neat little check that's added in there this called to stir copy down here that's what's actually going to take in the data from the pointer we passed in and copy it i

Original Description

Big thank you to Brilliant for sponsoring this video! To try Brilliant for free (for 30 days) and to get a 20% discount, visit: https://Brilliant.org/davidbombal // YouTube video REFERENCE // Free Exploit development training (beginner and advanced) https://youtu.be/LWmy3t84AIo Buffer Overflow Hacking Tutorial (Bypass Passwords): https://youtu.be/c2BvS2VqDWg // Stephen's Social // X: https://x.com/Steph3nSims YouTube: https://www.youtube.com/@OffByOneSecurity // Stephen RECOMMENDS // Disassemblers: Binary Ninja: https://binary.ninja/ IDA Pro: https://hex-rays.com/products/%20ida/ Ghidra: https://ghidra-sre.org/ Free Learning Resources: An Intro to C for Windows Dev: https://www.sans.org/webcasts/intro-c-windows-devs/ Books Gray Hat Hacking Series by various authors: US https://amzn.to/3B1FeIK UK https://amzn.to/3A920AL The IDA Pro Book, 2nd Edition: The Unofficial Guide to the World's Most Popular Disassembler Second Edition by Chris Eagle US https://amzn.to/3Yv3srw UK https://amzn.to/3Wtz8e6 // David's SOCIAL // Discord: https://discord.com/invite/usKSyzb X: https://www.x.com/davidbombal Instagram: https://www.instagram.com/davidbombal LinkedIn: https://www.linkedin.com/in/davidbombal Facebook: https://www.facebook.com/davidbombal.co TikTok: http://tiktok.com/@davidbombal YouTube: https://www.youtube.com/@davidbombal // MY STUFF // https://www.amazon.com/shop/davidbombal // SPONSORS // Interested in sponsoring my videos? Reach out to my team here: sponsors@davidbombal.com // MENU // 00:00 - Intro 01:06 - Brilliant sponsored segment 02:36 - Stephen Sims // Off By One Security YouTube channel 04:02 - Hello World 06:11 - Learning the C programming language 09:34 - Introduction to reverse engineering 13:57 - Functions explained 16:43 - Stripped explained 18:03 - Disassemble explained // Differences between flavors 25:11 - History behind the two flavors 25:58 - Disassemble explained continued 26:22 - Return oriented programming explained 27:
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from David Bombal · David Bombal · 0 of 60

← Previous Next →
1 RYU SDN Controller Part 4: Graphical User Interface (GUI): Practical GNS3 SDN and OpenFlow
RYU SDN Controller Part 4: Graphical User Interface (GUI): Practical GNS3 SDN and OpenFlow
David Bombal
2 HPE Network Protector SDN Application Part 1 - Introduction
HPE Network Protector SDN Application Part 1 - Introduction
David Bombal
3 HPE Network Protector SDN Application Part 2 : DNS Interception using OpenFlow
HPE Network Protector SDN Application Part 2 : DNS Interception using OpenFlow
David Bombal
4 HPE Network Protector SDN Application Part 3 - Lab Setup using Physical Switches
HPE Network Protector SDN Application Part 3 - Lab Setup using Physical Switches
David Bombal
5 HPE Network Protector SDN Application Part 4 - Demo of malicious websites blocked
HPE Network Protector SDN Application Part 4 - Demo of malicious websites blocked
David Bombal
6 HPE Network Protector SDN Application Part 5 - Demo OpenFlow table interception flows
HPE Network Protector SDN Application Part 5 - Demo OpenFlow table interception flows
David Bombal
7 HPE Network Protector SDN Application Part 6 - Demo of Physical Switch configuration
HPE Network Protector SDN Application Part 6 - Demo of Physical Switch configuration
David Bombal
8 HPE Network Protector SDN Application Part 7 - Demo Service Insertion Tunnel / GRE Tunnel
HPE Network Protector SDN Application Part 7 - Demo Service Insertion Tunnel / GRE Tunnel
David Bombal
9 HPE Network Protector SDN Application Part 8 - Demo SDN OpenFlow Reporting
HPE Network Protector SDN Application Part 8 - Demo SDN OpenFlow Reporting
David Bombal
10 HPE Network Protector SDN Application Part 9 - Demo switches interception of DNS traffic
HPE Network Protector SDN Application Part 9 - Demo switches interception of DNS traffic
David Bombal
11 GNS3 Talks: GNS3 version 1.5.X Appliance Tips
GNS3 Talks: GNS3 version 1.5.X Appliance Tips
David Bombal
12 CCNA 200-125 Exam: AAA demo: TACACS+ with GNS3
CCNA 200-125 Exam: AAA demo: TACACS+ with GNS3
David Bombal
13 GNS3 2.0.0 beta 2 install
GNS3 2.0.0 beta 2 install
David Bombal
14 CCNA #012: Learn SNMP with GNS3, Wireshark and Solarwinds NPM - CCNA 200-125 exam
CCNA #012: Learn SNMP with GNS3, Wireshark and Solarwinds NPM - CCNA 200-125 exam
David Bombal
15 CCNA #013: Spanning Tree CCNA Exam Questions: Know the answer? CCNA 200-125 exam
CCNA #013: Spanning Tree CCNA Exam Questions: Know the answer? CCNA 200-125 exam
David Bombal
16 GNS3 2.0.0 beta : GNS3 VM integration with GNS3 GUI
GNS3 2.0.0 beta : GNS3 VM integration with GNS3 GUI
David Bombal
17 CCNA #018: Routing exam questions: Who wins? OSPF, EIGRP or RIP? Sure? CCNA 200-125 exam
CCNA #018: Routing exam questions: Who wins? OSPF, EIGRP or RIP? Sure? CCNA 200-125 exam
David Bombal
18 CCNA #019: Spanning Tree CCNA Exam Questions: Root Bridge, Root Port and more: CCNA 200-125 exam
CCNA #019: Spanning Tree CCNA Exam Questions: Root Bridge, Root Port and more: CCNA 200-125 exam
David Bombal
19 GNS3 Download, installation and configuration - GNS3 1.5.3 and Windows 10
GNS3 Download, installation and configuration - GNS3 1.5.3 and Windows 10
David Bombal
20 CCNA #023 EIGRP Neighbor Troubleshooting (DUAL Issues) for the CCNA 200-125 Exam
CCNA #023 EIGRP Neighbor Troubleshooting (DUAL Issues) for the CCNA 200-125 Exam
David Bombal
21 GNS3 2.0 Architecture and schema Part 1: What is the GNS3 Controller?
GNS3 2.0 Architecture and schema Part 1: What is the GNS3 Controller?
David Bombal
22 GNS3 2.0 Architecture and schema Part 2: Emulators and virtualization
GNS3 2.0 Architecture and schema Part 2: Emulators and virtualization
David Bombal
23 CCNA #028 VTP Troubleshooting for the CCNA 200-125 Exam
CCNA #028 VTP Troubleshooting for the CCNA 200-125 Exam
David Bombal
24 CCNA #029 VTP & DTP Troubleshooting for the CCNA 200-125 Exam
CCNA #029 VTP & DTP Troubleshooting for the CCNA 200-125 Exam
David Bombal
25 CCNA #030 VTP Troubleshooting for the CCNA 200-125 Exam
CCNA #030 VTP Troubleshooting for the CCNA 200-125 Exam
David Bombal
26 GNS3 : How to download Cisco IOS images and VIRL images. Which is the best? How do you get them?
GNS3 : How to download Cisco IOS images and VIRL images. Which is the best? How do you get them?
David Bombal
27 GNS3 ASA setup: Import and configure Cisco ASAv with GNS3
GNS3 ASA setup: Import and configure Cisco ASAv with GNS3
David Bombal
28 GNS3 switching setup and options: Cisco and other switching options in GNS3
GNS3 switching setup and options: Cisco and other switching options in GNS3
David Bombal
29 GNS3 switching setup and options Part 2: GNS3 unmanaged built-in switch
GNS3 switching setup and options Part 2: GNS3 unmanaged built-in switch
David Bombal
30 GNS3 switching setup and options Part 3: Router on a sick with GNS3 unmanaged built-in switch
GNS3 switching setup and options Part 3: Router on a sick with GNS3 unmanaged built-in switch
David Bombal
31 GNS3 switching setup and options Part 4: Etherswitch Router for Cisco Dynamips Part 1
GNS3 switching setup and options Part 4: Etherswitch Router for Cisco Dynamips Part 1
David Bombal
32 GNS3 switching setup and options Part 5: Etherswitch Router for Cisco Dynamips Part 2
GNS3 switching setup and options Part 5: Etherswitch Router for Cisco Dynamips Part 2
David Bombal
33 GNS3 switching setup and options Part 6: Etherswitch, Wireshark, 802.1Q, InterVLAN routing
GNS3 switching setup and options Part 6: Etherswitch, Wireshark, 802.1Q, InterVLAN routing
David Bombal
34 GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 1: GNS3 Switching Part 7
GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 1: GNS3 Switching Part 7
David Bombal
35 GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 2: GNS3 Switching Part 8
GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 2: GNS3 Switching Part 8
David Bombal
36 GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 3: GNS3 Switching Part 9
GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 3: GNS3 Switching Part 9
David Bombal
37 GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 4: GNS3 Switching Part 10
GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 4: GNS3 Switching Part 10
David Bombal
38 GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 5: GNS3 Switching Part 11
GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 5: GNS3 Switching Part 11
David Bombal
39 GNS3 Nexus (NX-OSv) switch setup and configuration Part 1: GNS3 switching options Part 12
GNS3 Nexus (NX-OSv) switch setup and configuration Part 1: GNS3 switching options Part 12
David Bombal
40 GNS3 Nexus (NX-OSv) switch setup and configuration Part 2: GNS3 switching options Part 13
GNS3 Nexus (NX-OSv) switch setup and configuration Part 2: GNS3 switching options Part 13
David Bombal
41 GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 6: GNS3 Switching Part 14
GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 6: GNS3 Switching Part 14
David Bombal
42 GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 7: GNS3 Switching Part 15
GNS3 Talks: Docker, Open vSwitch, SDN and OpenFlow Part 7: GNS3 Switching Part 15
David Bombal
43 GNS3 Cisco CSR 1000v setup and configuration Part 1: GNS3 NFV
GNS3 Cisco CSR 1000v setup and configuration Part 1: GNS3 NFV
David Bombal
44 GNS3 Cisco CSR 1000v setup and configuration Part 2: GNS3 NFV
GNS3 Cisco CSR 1000v setup and configuration Part 2: GNS3 NFV
David Bombal
45 GNS3 Talks: Use the NAT node to connect GNS3 to the Internet easily!
GNS3 Talks: Use the NAT node to connect GNS3 to the Internet easily!
David Bombal
46 GNS3 Talks: GNS3 2.0 RC1 is now available
GNS3 Talks: GNS3 2.0 RC1 is now available
David Bombal
47 GNS3 Talks: GNS3 2.0 Portable Projects - easily export and import GNS3 projects
GNS3 Talks: GNS3 2.0 Portable Projects - easily export and import GNS3 projects
David Bombal
48 GNS3 Talks: Multiple clients sharing projects in real time, plus console session shadowing!
GNS3 Talks: Multiple clients sharing projects in real time, plus console session shadowing!
David Bombal
49 CCNA #035 NAT Troubleshooting Scenario 1 - Can you find the issue? CCNA Exam 200-125 troubleshooting
CCNA #035 NAT Troubleshooting Scenario 1 - Can you find the issue? CCNA Exam 200-125 troubleshooting
David Bombal
50 CCNA #036 NAT Troubleshooting Scenario 2 - Can you find the issue? CCNA Exam 200-125 troubleshooting
CCNA #036 NAT Troubleshooting Scenario 2 - Can you find the issue? CCNA Exam 200-125 troubleshooting
David Bombal
51 GNS3 Talks: ESXi, GNS3 VM and KVM support Part 1: leverage servers and the cloud
GNS3 Talks: ESXi, GNS3 VM and KVM support Part 1: leverage servers and the cloud
David Bombal
52 CCNA #037 OSPF Troubleshooting - can you find the issue? CCNA Exam 200-125 troubleshooting
CCNA #037 OSPF Troubleshooting - can you find the issue? CCNA Exam 200-125 troubleshooting
David Bombal
53 GNS3 Talks: ESXi, GNS3 VM and KVM support Part 2:  leverage servers and the cloud
GNS3 Talks: ESXi, GNS3 VM and KVM support Part 2: leverage servers and the cloud
David Bombal
54 CCNA #038 NAT Troubleshooting Scenario 3 - Can you find the issue? CCNA Exam 200-125 troubleshooting
CCNA #038 NAT Troubleshooting Scenario 3 - Can you find the issue? CCNA Exam 200-125 troubleshooting
David Bombal
55 CCNA #039 - OSPF DR, BR and DROTHER Election - do you know the answers?
CCNA #039 - OSPF DR, BR and DROTHER Election - do you know the answers?
David Bombal
56 CCNA #040 NAT Troubleshooting Scenario 4 - Can you find the issue? CCNA Exam 200-125 troubleshooting
CCNA #040 NAT Troubleshooting Scenario 4 - Can you find the issue? CCNA Exam 200-125 troubleshooting
David Bombal
57 GNS3 Talks: Arista vEOS GNS3 import and configuration Part 1
GNS3 Talks: Arista vEOS GNS3 import and configuration Part 1
David Bombal
58 CCNA #041 - OSPF DR, BR and DROTHER Election - do you know the answers?
CCNA #041 - OSPF DR, BR and DROTHER Election - do you know the answers?
David Bombal
59 GNS3 Talks: Arista vEOS GNS3 import and configuration Part 2
GNS3 Talks: Arista vEOS GNS3 import and configuration Part 2
David Bombal
60 GNS3 Talks: ipterm: Linux, Docker, Python, SDN and more! Part 1
GNS3 Talks: ipterm: Linux, Docker, Python, SDN and more! Part 1
David Bombal

This video tutorial provides a comprehensive introduction to reverse engineering and cybersecurity, covering topics such as compiling and running C programs, using GDB for debugging, and understanding memory, signals, and computer speeds. It also delves into shared libraries, dynamic linking, and buffer overflows, providing a solid foundation for further learning. The tutorial utilizes tools such as GCC, GDB, and ELF executable and linking format, and touches on topics like procedure linkage tab

Key Takeaways
  1. Compile a C program with GCC
  2. Run the compiled program with GDB
  3. Use GDB to disable extensions and show dynamic dependencies and internal functions
  4. Disassemble a function using GDB
  5. Switch the disassembly flavor from AT&T to Intel syntax
  6. Understand the procedure prologue and epilogue inserted by the compiler
  7. Identify the stack frame and return pointer in a function
  8. Recognize the potential for buffer overflows and hijacking code execution
💡 Buffer overflows can be used to hijack code execution by getting a hold of the return pointer, and understanding the procedure linkage table and global offset table is crucial for reverse engineering and cybersecurity.

Related Reads

📰
Active Directory Enumeration & Password Spraying: A Hands-On Guide
Learn hands-on techniques for Active Directory enumeration and password spraying to enhance your internal penetration testing skills in Microsoft Windows environments
Medium · Cybersecurity
📰
The Quantum Internet Explained: How the Next Generation of Communication Could Be Unhackable
Learn how the quantum internet can revolutionize cybersecurity with unhackable communication, and why it matters for the future of data transfer
Medium · Cybersecurity
📰
Zero Trust Starts Before Login: Lessons From Cloud Security
Learn how Zero Trust security starts before login and its importance in cloud security
Medium · DevOps
📰
Zero Trust Starts Before Login: Lessons From Cloud Security
Learn how Zero Trust security starts before login and why continuous verification is crucial for cloud security
Medium · Cybersecurity

Chapters (12)

Intro
1:06 Brilliant sponsored segment
2:36 Stephen Sims // Off By One Security YouTube channel
4:02 Hello World
6:11 Learning the C programming language
9:34 Introduction to reverse engineering
13:57 Functions explained
16:43 Stripped explained
18:03 Disassemble explained // Differences between flavors
25:11 History behind the two flavors
25:58 Disassemble explained continued
26:22 Return oriented programming explained
Up next
What is reCAPTCHA v3 Explained with Examples
VLR Software Training
Watch →