Security-Oriented C Tutorial 0x19 - Functions Part V: Passing by Reference
Hello there! This will probably be the final tutorial on functions where we will be looking over a method called pass by reference. This technique allows us to modify large amounts of data without the overhead and return multiple values. Let's go!
Until now, we've been using function arguments with a method called pass by value which essentially copies the data from the callee to the caller through the stack. If you've forgotten, here are the details in Tutorial 0x0F. Some issues we might face is that we are required to copy the entire value onto the stack for it to be used and if that data were large, it could take up valuable resources. In addition, if we were required to return multiple values, we would probably require a struct to be able to do this.
Passing by reference is a solution to the problems we face in the above scenario. Instead of copying entire values onto the stack, all that is given to the function is the reference to the data. In doing so, we can directly alter the original value instead of a copy of the original value.
We can see that our swap function does not return a value. Instead of passing our function the values of our variables num1 and num2, we are giving it their addresses. Inside our function, we declare a temporary variable to hold one of the values while we perform the switch. To do this, we need to dereference the pointers to access the values.
Let's take a look at what's happening inside memory.
We set breakpoints in main and swap so that we can identify our variables num1 (yellow) and num2 (blue).
In the first stack analysis, we locate and identify our variables' data and their addresses on the stack. num1 is at address 0xffffd098 with the hex value of 0x2a and num2 is at address 0xffffd09c and has a hex value of 0x44.
When we call swap, we pass it the addresses of our two variables. In the second stack analysis, we find the addresses of our first and second variables. first is located at address 0xffffd080 with the hex value of 0xffffd098 (address of num1) and second is located at address 0xffffd084 with the hex value of 0xffffd09c (address of num2).
Interrupting at line 8, before we exit the swap function, we can see that the values in our stack have swapped.
The same goes for arrays. Back in Tutorial 0x10 - Pointers and Addresses, I touched on arrays and showed that the array is a reference to its first index. Let's see what happens when we pass it into a function.
Notice again that the function editArray has no return value. Since the array is passed into the function as reference, any changes to the array in editArray would directly affect it in main.
To get the number of elements in our int array, we need to get the size of the buffer in bytes with the sizeof operator and then divide it by the size of an int because remember that each int has a size of 4 bytes.
Same expectation as the previous example.
The scanf function is a real-world demonstration of multiple return values. It returns the number of successfully read inputs and also sets given variables' values.
We can see that err is capturing the return value and n is going to be assigned a value. Again, n is passed by reference to allow the function to be able to return an error-checking value while at the same time, assign values given through variable arguments.
Passing by reference has its advantages but we must be aware that when doing so, we make sure that we don't do anything funny which would accidentally modify the contents. This especially goes for strings as char arrays.
This pretty much concludes the basics of functions. In the next tutorial, we will go over the linked list data structure and finish off the basic C standard series. After this, I will cover the Windows API and its documentation provided by the MSDN which will help us build functionality for our malware in the malware sub-series. Stay tuned!