├── Pointers ├── FunctionPointers │ ├── CommandHandler.c │ └── README.md ├── PassByValue-Ref │ └── README.md └── Pointers-to-Pointers │ └── README.md └── README.md /Pointers/FunctionPointers/CommandHandler.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void Create(); 5 | void Help(); 6 | 7 | typedef void (*funcptr)(void); // 'funcptr' is a synonym for the type ‘pointer to function which returns void’ 8 | 9 | // Structure to hold command information 10 | typedef struct { 11 | char* name; // Command name 12 | char* help; 13 | funcptr execute; // Function to execute the command 14 | } commandStruct; 15 | 16 | // Command table 17 | commandStruct commands[] = { 18 | {"help", "Help menu", Help}, 19 | {"create", "Create a linked list", Create}, 20 | {NULL, NULL, NULL} // End of the command table 21 | }; 22 | 23 | void Create() { 24 | printf("Create function called.\n"); 25 | } 26 | 27 | void Help() { 28 | printf("Commands:\n"); 29 | 30 | for (int i = 0; commands[i].name != NULL; i++) { 31 | printf("\t%s - %s\n", commands[i].name, commands[i].help); 32 | } 33 | } 34 | 35 | // CommandHandler reads a command from the user, 36 | // searches for it in the command table, 37 | // and executes the corresponding function 38 | void CommandHandler(char* input) { 39 | 40 | for (int i = 0; commands[i].name != NULL; i++) { 41 | if (strcmp(commands[i].name, input) == 0) { 42 | commands[i].execute(); // Execute the matched command's function 43 | // (*commands[i].execute)(); works too 44 | return; 45 | } 46 | } 47 | printf("Command not found. Type 'help' for a list of commands.\n"); 48 | } 49 | 50 | int main(void) 51 | { 52 | char input[256] = { 0 }; 53 | printf("Command > "); 54 | 55 | if (fgets(input, sizeof(input), stdin) != NULL) { 56 | input[strcspn(input, "\n")] = '\0'; // Strip newline 57 | } 58 | 59 | CommandHandler(input); // Handle the command 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /Pointers/FunctionPointers/README.md: -------------------------------------------------------------------------------- 1 | # Function Pointers in C 2 | 3 | Here is the code explanation for a simple command handler (`CommandHandler.c`) which demonstrates the use of function pointers: 4 | 5 | ## Declaration: 6 | On line 7, we declare the function pointer `funcptr` with `typedef`: 7 | ```c 8 | typedef void (*funcptr)(void); 9 | ``` 10 | 11 | `*` indicates that `funcptr` is a pointer. However, the function-call operator `()` holds higher precedence than the pointer operator `*`. Therefore, we need to override it with extra parentheses around `*funcptr` to specify that it is a pointer to a function which returns void. 12 | 13 | `funcptr` by default takes no arguments. It could, however, be easily modified to take two integers as arguments, like so: 14 | ```c 15 | typedef void (*funcptr)(int, int); 16 | ``` 17 | 18 | In the `commandStruct` structure, the `execute` field is set to type `funcptr`. 19 | 20 | ## Assignment: 21 | In the `commands` array, the `execute` field is assigned the addresses of the `Help` and `Create` functions. 22 | 23 | Note that `{"help", "Help menu", Help}` could be written as `{"help", "Help menu", &Help}` but in C, the name of a function naturally represents a pointer to the function, so the `&` operator is unnecessary, similar to how arrays are treated. 24 | 25 | ## Function Calls via Pointers: 26 | Finally, in `CommandHandler`, we call the function to which the pointer refers: 27 | ```c 28 | (*commands[i].execute)(); 29 | ``` 30 | 31 | Here we dereference (`*`) the pointer `execute` to obtain the function it points to and call it. So, like before, the extra parentheses around `*commands[i].execute` are used for the same reason as they were in the declaration of `funcptr`. That being said, the function can also be called with just: 32 | ```c 33 | commands[i].execute(); 34 | ``` 35 | 36 | This is because if you use a function pointer with a call operation `()`, it is clear to the compiler from the context that you intend to call a function. Besides assigning, comparing, or directly calling function pointers, there are no other operations you can perform on them, so the compiler can easily understand the intended action. 37 | -------------------------------------------------------------------------------- /Pointers/PassByValue-Ref/README.md: -------------------------------------------------------------------------------- 1 | # Pass by Value and Pass by Reference in C: 2 | 3 | Here is the code and explanation for a simple implementation of **pass by value** and **pass by reference**: 4 | 5 | ```c 6 | #include 7 | 8 | void A(int value) { 9 | value = value + 1; 10 | } 11 | 12 | void B(int* valueRef) { 13 | *valueRef = *valueRef + 1; 14 | } 15 | 16 | int main(void) { 17 | int value; 18 | value = 7; 19 | printf("Initial value : %d\n\n", value); 20 | 21 | A(value); // Pass by value - does not change the original 'value' 22 | printf("value AFTER A() call:\n"); 23 | printf("%d\n", value); 24 | 25 | B(&value); // Pass by reference - changes the original 'value' 26 | printf("value AFTER B() call:\n"); 27 | printf("%d\n", value); 28 | 29 | return 0; 30 | } 31 | ``` 32 | 33 | Function `A` receives a copy of the value `7` from the caller in `main`, which is stored on the stack. It is a ‘copy’ because it is independent from the original value in main. Inside function `A`, this copied value (`7`) is incremented by `1`. However, since the copy is local only to function `A`, the original value in `main` remains unchanged. Once function `A` exits, the local copy (now `8`) is deallocated. 34 | 35 | Function `B`, on the other hand, is passed a pointer to the original value `7`. This allows function `B` to directly access and modify the original value stored in `main`. Function `B` uses a dereference (`*`) on the pointer to get at the value `7` in `main` and increment it by `1`. This change persists even after function `B` exits. 36 | -------------------------------------------------------------------------------- /Pointers/Pointers-to-Pointers/README.md: -------------------------------------------------------------------------------- 1 | # Pointers to Pointers and How Data is Stored in C: 2 | Here is example that demonstrates the handling of pointers to pointers and how data is stored: 3 | 4 | ```c 5 | #include 6 | 7 | void C(char** ptr) // C takes as its parameter a pointer to a pointer 8 | // *ptr is the original pointer in main 9 | { 10 | char* cp = "ABCDE"; 11 | *ptr = cp; // Here we dereference *ptr and set it to what cp points to ("ABCDE") 12 | // "ABCDE" is stored in the read-only data segment 13 | } 14 | 15 | void D(char** ptr) 16 | { 17 | char c[] = "FGHIJ"; // c is a local array stored on the stack 18 | *ptr = c; // *ptr is set to what c points to ("FGHIJ") but will be deallocated once D exits 19 | } 20 | 21 | int main(void) 22 | { 23 | char* ptr = NULL; 24 | 25 | C(&ptr); // Pass the address of ptr to function C 26 | printf("ptr's value AFTER C() call:\n%s\n", ptr); 27 | 28 | D(&ptr); 29 | printf("ptr's value AFTER D() call:\n%s\n", ptr); // Accesses deallocated memory - runtime error 30 | 31 | return 0; 32 | } 33 | ``` 34 | 35 | After function `D`, `ptr` is not set to `FGHIJ` after `D` exits. This is because `FGHIJ` is stored on the stack within function `D` as a local array and will be deallocated once the function exits. It is local to only function `D`. So, after function `D` exits, `ptr` points to deallocated memory which would lead to an error if accessed. In contrast, in function `C`, the pointer `cp` is stored on the stack and points to the string `ABCDE` which is stored in the read-only data segment and can be accessed after the function exits. 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C from Scratch 2 | 3 | In March 2023, I decided to learn C from scratch. Throughout this journey, I used a variety of resources—some were beneficial, while others not as much. I have compiled a list of the most helpful resources into a roadmap for anyone who wishes to do the same. It should save you some time sifting through mediocre materials. 4 | 5 | Once I felt comfortable with C, I went lower—specifically, x86-64 Assembly and x86-64 OS Internals. I have included the resources I used for these topics as well. 6 | 7 | Note, this is not a 'learn C in 10 hours' roadmap. A more realistic estimate would be to add a couple more zeros. 8 | 9 | # C 10 | ### [CS50 Introduction to Computer Science](https://cs50.harvard.edu/x/2023/) 11 | 12 | If you have not had any formal education in computer science, I recommend to start with the 2023 version of CS50 (that's the one I completed, so I can only recommend that). Start at **week 0** and continue through to **week 6**. For each week, make sure to watch the lecture, section, shorts, and complete the problem sets. 13 | 14 | ### [h0mbre’s (project based) C course](https://github.com/h0mbre/Learning-C) 15 | 16 | Next, move on to h0mbre’s project-based C course. After CS50, you should be able to breeze through this course relatively quickly. I recommend this because it is an excellent opportunity to practice and apply your skills without the support structures provided in CS50. 17 | 18 | You can find my solutions to the assignments [here](https://github.com/theokwebb/Learning-C). 19 | 20 | There may be some instances where you need to review or deepen your understanding of certain topics. Here are a few areas I struggled with and needed additional information to fully understand: 21 | 22 | #### Pointers 23 | - [Pointers and Memory](http://cslibrary.stanford.edu/102/PointersAndMemory.pdf) 24 | - [A Tutorial on Pointers and Arrays in C by Ted Jensen](https://github.com/jflaherty/ptrtut13/tree/master/md) 25 | 26 | #### Input Sanitization 27 | - [A beginners' guide away from scanf()](https://www.sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html) 28 | 29 | #### Data Structures 30 | - [Linked Lists](http://cslibrary.stanford.edu/105/LinkedListProblems.pdf) 31 | 32 | #### Code Examples and Explanations 33 | Here are some code snippets and explanations I’ve written for some intermediate C concepts that might be useful to you: 34 | - [Pass by Value and Pass by Reference]( https://github.com/theokwebb/C-from-Scratch/tree/main/Pointers/PassByValue-Ref) 35 | - [Pointers to Pointers and How Data is Stored]( https://github.com/theokwebb/C-from-Scratch/tree/main/Pointers/Pointers-to-Pointers) 36 | - [Function Pointers]( https://github.com/theokwebb/C-from-Scratch/tree/main/Pointers/FunctionPointers) 37 | 38 | #### Other Comprehensive Guides 39 | - [CS107 Computer Organization and Systems](https://stanford.edu/~cgregg/cgi-bin/107-reader/) 40 | 41 | CS107 reader includes a primer on C along with lots of other useful information related to the language and computer science. 42 | 43 | - [C Programming by Steve Summit](https://www.eskimo.com/~scs/cclass/cclass.html) 44 | 45 | I stumbled upon this gem shortly after I first made this post in May, 2024 and use it often to revisit various C concepts. Steve's explanations are incredibly well-written, and the course exercises are very helpful to drive home the fundamentals. There’s also a load of quality information related to computer science on the site. 46 | 47 | - [C Programming A Modern Approach - Second Edition by K. N King](https://archive.org/details/c-programming-a-modern-approach-2nd-ed-c-89-c-99-king-by) 48 | 49 | If you encounter a concept that's not covered in the other resources, such as unions or enumerations, this book is an excellent reference. 50 | 51 | ### Individual Project 52 | By this point, you should be prepared to start your own project. Personally, I found it hard to choose one, as I was constantly searching for the perfect 'beginner-friendly' project which aligned with my interests. However, I realised that this approach isn’t beneficial at all. A calculator, hash table, or tic-tac-toe project will just bore you. Pursue a project that genuinely interests you, regardless of its difficulty. You will likely face some setbacks, but the valuable lessons you learn through these experiences are what truly matter. 53 | 54 | If you’re interested in malware development, head over to [Vx Underground](https://vx-underground.org/) and read some of their [white papers](https://github.com/vxunderground/VXUG-Papers) and malware [source code](https://github.com/vxunderground/MalwareSourceCode). 55 | 56 | I decided to develop a kernel driver and a rootkit. If you intend to delve deeper into x86-64 OS Internals, I would highly recommend this route as Windows kernel development and x86-64 OS Internals are closely interconnected. However, you will first need to learn x86-64 Assembly. 57 | 58 | # x86-64 Assembly 59 | 60 | ### [Architecture 1001: x86-64 Assembly](https://p.ost2.fyi/courses/course-v1:OpenSecurityTraining2+Arch1001_x86-64_Asm+2021_v1/about) 61 | 62 | Arch1001 is absolutely incredible and includes tons of practical labs that help cement concepts. You will not be bored with Xeno. 63 | 64 | In Arch1001, there are some optional refreshers for fundamental topics like bits, logic, C data types, and two's complement. However, I found that I needed more detailed information. Chapter 2 of [Computer Systems: A Programmer's Perspective](https://www.pearson.com/en-us/subject-catalog/p/computer-systems-a-programmers-perspective/P200000003479/9780138105396) and the [CS107 Computer Organization and Systems](https://stanford.edu/~cgregg/cgi-bin/107-reader/) proved to be the most helpful. If money is an issue, just use the CS107 reader as it is free. 65 | 66 | I have posted a number of writeups to Arch1001 on my [GitHub](https://github.com/theokwebb/my-writeups) which you may find helpful. 67 | 68 | If you enjoyed the binary bomb lab in Arch1001, check out [Crackmes.One](https://crackmes.one/). 69 | 70 | # x86-64 OS Internals 71 | 72 | If you're new to Operating Systems Internals, start with [Putting the "You" in CPU.](https://cpu.land/) It provides a nice overview of the topic before getting into the more in-depth resources below. 73 | 74 | ### [Architecture 2001: x86-64 OS Internals](https://p.ost2.fyi/courses/course-v1:OpenSecurityTraining2+Arch2001_x86-64_OS_Internals+2021_v1/about) 75 | 76 | Arch2001 is OS-agnostic, but there are some excellent OS-related resources that complement it, so I recommend to pick a path that you think will be most relevant to you and read the related Windows or Linux material below. 77 | 78 | ### Windows: 79 | 80 | For those interested in Windows, read at least the first four chapters of [Windows Kernel Programming, Second Edition](https://leanpub.com/windowskernelprogrammingsecondedition) before starting Arch2001. This will lay a solid foundation for the course. If you prefer video instruction, there’s the paid [Windows Kernel Programming 1](https://training.trainsec.net/windows-kernel-programming-1) course. I also recommend to read Chapter 1 of [Windows Internals, Part 1](https://www.microsoftpressstore.com/store/windows-internals-part-1-system-architecture-processes-9780735684188) and use the other chapters as a reference if you encounter any difficulties. 81 | 82 | ### Linux: 83 | 84 | For Linux, start with Chapter 1 of [Computer Systems: A Programmer's Perspective](https://www.pearson.com/en-us/subject-catalog/p/computer-systems-a-programmers-perspective/P200000003479/9780138105396) (CS:APP). Then, if you’re ever stuck on a topic in Arch2001, refer to the chapter on that topic in CS:APP. For me, Chapter 9 was key to properly understanding virtual memory. 85 | 86 | If you’re not very comfortable with the Linux command line, visit [pwn.college](https://pwn.college/linux-luminarium/). 87 | 88 | **Note**: No matter which path you take, CS:APP is an incredibly helpful resource. 89 | 90 | I have published a blog post on [Interrupt Handling and Stack Switching in x86-64 Architecture](https://theokwebb.github.io/posts/interrupt-handling-and-stack-switching/), inspired by some difficulties I faced in a lab from Arch2001. 91 | 92 | # 93 | 94 | I will continue to update this list as I encounter more helpful resources. 95 | --------------------------------------------------------------------------------