<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://docs.gamesense.gs/blog</id>
    <title>GameSense Documentation Blog</title>
    <updated>2022-12-26T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://docs.gamesense.gs/blog"/>
    <subtitle>GameSense Documentation Blog</subtitle>
    <icon>https://docs.gamesense.gs/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[Welcome to the blog!]]></title>
        <id>welcome</id>
        <link href="https://docs.gamesense.gs/blog/welcome"/>
        <updated>2022-12-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Welcome to the blog section of the docs!]]></summary>
        <content type="html"><![CDATA[<p>Welcome to the blog section of the docs!</p><p>Here you will find guides and other useful tutorials and posts that can further enhance your understanding of the GameSense API and potentially make you more creative.</p><p><strong>Want to share your knowledge for others to see and read?</strong></p><p>Open a pull request on <a href="https://github.com/gamesensical/docs" target="_blank" rel="noopener noreferrer">GitHub</a> with your post in a markdown-formatted file. Use the blog posts that already exist as an example of how to format your markdown files, and how to name them.</p>]]></content>
        <author>
            <name>Nexxed</name>
            <uri>https://gamesense.pub/forums/profile.php?id=3046</uri>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Guide: FFI Crash Course]]></title>
        <id>ffi-crash-course</id>
        <link href="https://docs.gamesense.gs/blog/ffi-crash-course"/>
        <updated>2020-10-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Hello! I have decided to write an in-depth FFI crash course to provide a place for anyone regardless of your experience to learn without looking through the dozens of possibly confusing scripts released here on the forum, which are generally undocumented and some are quite complex. This guide will act as a place for you to learn FFI's basics, plus some tips and tricks from me and others to become a more experienced and competent Lua developer.]]></summary>
        <content type="html"><![CDATA[<p>Hello! I have decided to write an in-depth FFI crash course to provide a place for anyone regardless of your experience to learn without looking through the dozens of possibly confusing scripts released here on the forum, which are generally undocumented and some are quite complex. This guide will act as a place for you to learn FFI's basics, plus some tips and tricks from me and others to become a more experienced and competent Lua developer.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="a-quick-explanation">A quick explanation<a class="hash-link" href="#a-quick-explanation" title="Direct link to heading">​</a></h3><p>Throughout the first section of this guide, I will be providing pseudo-C code snippets, as C comes built in with dedicated methods for certain, very important operations to us and is also the language that FFI provides an interface to, so knowledge of how it operates is completely necessary. The Lua equivalents of these operations require a more abstract thought process, as Lua does not provide explicit operations for the aforementioned functionality. I will be explaining these concepts in pseudo-C and then explaining how the same can be achieved in Lua, while calling back to earlier terminology we will have covered by then.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-ffi">What is FFI?<a class="hash-link" href="#what-is-ffi" title="Direct link to heading">​</a></h3><p>FFI - Also known (although rarely referred to) as the Foreign Function Interface - is an interface between different languages allowing them to interact with each other. FFI is generally used to create bindings to C/C++/etc libraries to higher level languages such as Python, Ruby but more importantly in our case, Lua. Bindings are just functions in the higher level languages that reach down into the lower level libraries and call their functions.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="ffi-in-gamesense">FFI in GameSense<a class="hash-link" href="#ffi-in-gamesense" title="Direct link to heading">​</a></h3><p>In GameSense, FFI is most commonly used to provide an interface into the CS:GO processes' memory, which allows a Lua developer to interact directly with the game, such as calling functions, without relying on a middleman such as the Lua API to do all the work. Since FFI provides an interface between Lua and C, using FFI requires some knowledge about low-level memory and how low level languages like C interact with it - we will be covering this later.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="memory-and-how-languages-interact-with-it">Memory and how languages interact with it<a class="hash-link" href="#memory-and-how-languages-interact-with-it" title="Direct link to heading">​</a></h2><p>In low-level languages such as C/C++ (I will be focusing on C as C++ provides some extra features for memory/pointer management that are far beyond the scope of this thread), memory can be interacted with directly, and all low-level/system software programming languages must provide us with a feature to do so. C provides us with a feature called pointers, these are essentially memory addresses, but ideally they will point to a specific variable, and this variable can be of any type (integer, long integer, floating point, string, even another pointer) and contain any value.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="the-two-types-of-pointers">The two types of pointers<a class="hash-link" href="#the-two-types-of-pointers" title="Direct link to heading">​</a></h3><p>The reason I said ideally in the previous paragraph is because a pointer may not always point to a variable, pointers that do not point to variable or any address are known as null pointers. This is where the divide between the two different types of pointers begins to show, they are known as SAFE and UNSAFE pointers. I will be covering safe pointers first as I find them easier to understand as there is less ambiguity, however when using FFI you will be seeing mostly unsafe pointers, however knowing how safe pointers work will make learning about unsafe pointers much easier. Below is an example of how a safe pointer is created.</p><div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#abd407">float</span><span class="token plain"> floating_point </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">100.f</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Create a variable (randomly chosen float type)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">float</span><span class="token operator" style="color:#95b806">*</span><span class="token plain"> floating_pointer </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token operator" style="color:#95b806">&amp;</span><span class="token plain">floating_point</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Create a pointer by using the &amp; operator.</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The variable floating_pointer now points to the variable floating_point (meaning it contains the address of the variable floating_point). It is called a safe pointer because we can say that the variable floating_point will always have an address in memory, and that the variable floating_pointer will always point to that variable.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="reading-memory-and-dereferencing">Reading memory and dereferencing<a class="hash-link" href="#reading-memory-and-dereferencing" title="Direct link to heading">​</a></h3><p>Lets say we only have access to the variable floating_pointer, yet we want to retrieve its value. This can be done through dereferencing. Dereferencing can be thought of like this, a pointer is a variable that references a value by memory address, and we are dereferencing the pointer to obtain its value. In other words, dereferencing is simply the act of reading the memory at the address stored in the pointer. Lets say that the address of the variable floating_point in memory was 0x1000, and now our pointer floating_pointer contains that value. In C we would dereference the variable using the <!-- -->*<!-- --> operator, placing it before the variable name as such:</p><div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#abd407">float</span><span class="token plain"> original_value </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token operator" style="color:#95b806">*</span><span class="token plain">floating_pointer</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The variable original_value will now contain 100.f.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="unsafe-pointers">Unsafe pointers<a class="hash-link" href="#unsafe-pointers" title="Direct link to heading">​</a></h3><p>Unsafe pointers are a much more complex subject, hence why they're getting their own subheading. An unsafe pointer is a pointer that we cannot say for sure if it points to a value of a given type. If we were to create a pointer with the type char<em> (char</em> is the type used for strings in C, the pointer points to the address of the first character in the string) and assign it some arbitrary address instead of an address we have retrieved from something that we know has to exist, we cannot say for sure that the address we assigned that pointer actually points to a string as we are able to give this pointer absolutely any numerical value, which may cause instability or a crash if we attempt to read from the pointer by dereferencing. Below is an example of an unsafe pointer in use.</p><div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#abd407">char</span><span class="token operator" style="color:#95b806">*</span><span class="token plain"> our_string </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token keyword" style="color:#abd407">char</span><span class="token operator" style="color:#95b806">*</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token number" style="color:#ae81ff">0x1234</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">char</span><span class="token plain"> first_character </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token operator" style="color:#95b806">*</span><span class="token plain">our_string</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This code, if compiled and ran will undoubtedly cause the application to crash as 0x1234 is almost certainly not a valid address.
You can also see, that we never use the &amp; operator that was discussed before, it is only used in the creation of safe pointers in C.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-unsafe-pointers">Why unsafe pointers?<a class="hash-link" href="#why-unsafe-pointers" title="Direct link to heading">​</a></h3><p>Because of the nature of what we are doing with FFI in GameSense, we only have access to the memory, not the higher level source code abstraction that would allow us to create safe pointers. Unsafe pointers are simply a way of telling our code how to interpret a memory address. Throughout this post I have said variable, but remember that these variables can be of any type (functions, engine defined structures, custom user defined types, and basic integral types). In the Lua API, we are provided with some features that allow us to easily scan memory and retrieve important engine structures and classes, these are client.find_signature and client.create_interface and both of these concepts will be explored later in the upcoming section.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="a-quick-introduction-into-memory-type-punning">A quick introduction into Memory type punning<a class="hash-link" href="#a-quick-introduction-into-memory-type-punning" title="Direct link to heading">​</a></h3><p>Type punning is the act of bypassing the type system that is implemented inside of programming languages. Type punning is more generally talked about in statically typed programming languages, not memory but although we are not dealing with the type system directly, we are dealing with the memory variables once managed by the type system. Look at this snippet from a hex editor, this was taken from a random executable file containing an XML string although this isn't important.</p><p><img loading="lazy" src="https://i.imgur.com/rjl7Ezy.png" class="img_ev3q"></p><p>From this snippet, we can clearly see from the ASCII representation on the right-hand-side of the image that it is the beginning of a XML string, however if i wanted to read the first 4 bytes of this string as a 4 byte integer, I could do this:</p><div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#abd407">int</span><span class="token operator" style="color:#95b806">*</span><span class="token plain"> int_pointer </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token keyword" style="color:#abd407">int</span><span class="token operator" style="color:#95b806">*</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token number" style="color:#ae81ff">0x405060</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">int</span><span class="token plain"> first_4_bytes </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token operator" style="color:#95b806">*</span><span class="token plain">int_pointer</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">// This could be tied into one line.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">int</span><span class="token plain"> first_4_bytes </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token operator" style="color:#95b806">*</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token keyword" style="color:#abd407">int</span><span class="token operator" style="color:#95b806">*</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token number" style="color:#ae81ff">0x405060</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The value of the variable first_4_bytes is now 0x6D783F3C (notice how its just the value of each of the first 4 bytes but going backwards).
The brackets and the int type name before the number is whats known as casting, im essentially telling the programming language how to interpret this memory address. This can be used on existing variables as well, given that they are numerical or are already a pointer just of a different type. This will be touched upon further in the next section. Remember! Memory is just a massive sequence of bytes, and it can be represented however you want it to, this is where a lot of the unsafety comes in.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="pointer-arithmetic">Pointer arithmetic<a class="hash-link" href="#pointer-arithmetic" title="Direct link to heading">​</a></h3><p>Pointer arithmetic is just like normal arithmetic like 1+2, but it takes something else into account. In all programming languages, types have size. This means that each type (byte, boolean, integer, long integer, string, floating point, etc.) have a specific size and some - like strings - can be dynamic in size. Pointer arithmetic simply takes the size of the type of the pointer into account when performing arithmetic operations (+ and -, multiplication and division are not used) on pointers. Here is an example of traversing an array using pointer arithmetic:</p><div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#abd407">int</span><span class="token plain"> our_array</span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token number" style="color:#ae81ff">10</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"> </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token number" style="color:#ae81ff">1</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">2</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">3</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">4</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">5</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">6</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">7</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">8</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">9</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">0</span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">int</span><span class="token operator" style="color:#95b806">*</span><span class="token plain"> our_array_ptr </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> our_array</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Both of these are identical, but im doing this for clarity to show that our_array really is a pointer.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">int</span><span class="token plain"> our_1st_value </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token operator" style="color:#95b806">*</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">our_array </span><span class="token operator" style="color:#95b806">+</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">1</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You would be right in assuming that the variable our_1st_value now contains 1, but theres more going on behind the scenes, let me demonstrate:</p><p><img loading="lazy" src="https://i.imgur.com/kdHyHYx.png" class="img_ev3q"></p><p>This is what our array looks like in memory, notice how each value is takes up 4 bytes. This is because the size of integers in C is 4 bytes, but our numbers are so small that they only use the first byte of the 4 they are given. Remember that our_array now contains the address 0x14001f068, and you may expect adding one to produce 0x14001f069, but remember that the next value in the array is 4 bytes away, so adding 1 really gives you 0x14001f06C as the size of the type has been taken into account.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="getting-practical-with-ffi">Getting practical with FFI<a class="hash-link" href="#getting-practical-with-ffi" title="Direct link to heading">​</a></h2><p>In this section we will cover actually using FFI and some of the features the GameSense Lua API provides us that makes our lives a lot easier. However, before reading on I must admit that in Lua, since it is not really intended to be a low-level language it does not come built in with some features that I would like which can make things awkward sometimes, but I will be covering ways of how we achieve what we need in the second subsection.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="getting-started">Getting started<a class="hash-link" href="#getting-started" title="Direct link to heading">​</a></h3><p>To actually start using FFI, you must include the library. This is done using the require keyword:</p><div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> ffi </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token function" style="color:#9499ff">require</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">"ffi"</span><span class="token punctuation" style="color:#f8f8f2">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>FFI can then be used as ffi.<!-- -->*<!-- --> throughout your script. I have linked the official Lua FFI documentation, so you can refer to that for some more functionality provided that I will not be covering.</p><div class="theme-admonition theme-admonition-info alert alert--info admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_S0QG"><p><strong>NOTE:</strong> functions such as <strong>ffi.c</strong> have been blocked for security reasons.</p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-to-achieve-things-in-lua">How to achieve things in Lua<a class="hash-link" href="#how-to-achieve-things-in-lua" title="Direct link to heading">​</a></h3><p>Lua does not provide us with a dedicated operator for dereferencing pointers like C does, but we're in luck because we can treat our pointer like an array with only one element, because in memory an array is really just a pointer to the first element of the array (like strings are pointers to the first character in C). So if we wish to access the first (and only) element of our "array" we can use... <!-- -->[0]<!-- -->! Look at the following example:</p><div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">byte our_array</span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token number" style="color:#ae81ff">5</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"> </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token number" style="color:#ae81ff">0x74</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">0x20</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">0x62</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">0x65</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">0x20</span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>In the above snippet, we see an array getting declared and initialised with 5 elements, I have provided an example of what it would look like in memory if this was to be stored directly in data (as a global variable in a C program).</p><p><img loading="lazy" src="https://i.imgur.com/ZEyeY8S.png" class="img_ev3q"></p><p>You can see that each value has been stored as a single byte, and that our_array has been given the address 0x400060. Now as I have said before, to us, our_array is just an array, but what really happens is it is turned into a pointer of type byte<!-- -->*<!-- --> and trying to do certain things, such as printing this array will instead print the address of the array. Reading from the array using <!-- -->[n]<!-- --> simply adds n to the pointer, while taking Pointer Arithmetic into account and dereferencing, so these are all equivalent:</p><div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#abd407">int</span><span class="token plain"> first_value </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token operator" style="color:#95b806">*</span><span class="token plain">our_array</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Dereferencing will just give the first value</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">int</span><span class="token plain"> first_value </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> our_array</span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token number" style="color:#ae81ff">0</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// Same as regular dereferencing, as we are just adding 0.</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>So we can imagine, that if we have a pointer it is, in memory, identical to an array containing one value, both are variables that contain an address that points to one single value, so we use <!-- -->[0]<!-- --> to dereference in Lua.</p><p>So now we know how to read from our pointers, but how do we create them? Well, the Lua API provided to us comes with 2 important functions that have been briefly mentioned before.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="signatures-and-signature-scanning">Signatures and signature scanning<a class="hash-link" href="#signatures-and-signature-scanning" title="Direct link to heading">​</a></h3><p>Signatures are simply sequences of bytes in memory, they consist of a signature and a mask, the mask tells us which values can be wildcards (they can be any value, I'll explain why this is important later) and which must be present. The signature is the actual pattern in memory. They are most commonly represented in 2 ways, raw byte strings and IDA's style, however esoterik decided to be a cretin and use some unloved god-child mix of the two. Below are some examples of each:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">IDA Style: 55 8B EC 83 E4 ? ? ? ? 53 56 57 8B F1 E8</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">- The ?'s represent the wildcards.</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">Code Style: \x55\x8B\xEC\x83\xE4\x00\x00\x00\x00\x53\x56\x57\x8B\xF1\xE8, xxxxx????xxxxxx</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">- The ?'s in the second part are the wildcards.</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">GameSense Style: \x55\x8B\xEC\x83\xE4\xCC\xCC\xCC\xCC\x53\x56\x57\x8B\xF1\xE8</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">- The \xCC's represent the wildcards.</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>For IDA users, this modified version of Aidan Khoury's SigMaker can be used to create GameSense style code signatures:
<a href="https://gamesense.pub/forums/viewtopic.php?id=22768" target="_blank" rel="noopener noreferrer">SigMaker extension by infirms1337</a></p><p>Here is a quick example of how signatures can be used to find a function:
In the Source Engine, there is a function in the C_CSPlayer class called SetAbsAngles. Now the class C_CSPlayer gets updated a lot so therefore the index of this function (think of functions in classes like an array for now, I'll talk more about this in a future update) may change a lot so I'm going to sig this function. Using IDA or some other means, I can locate the function and use the SigMaker plugin to generate the signature <code>55 8B EC 83 E4 F8 83 EC 64 53 56 57 8B F1 E8</code>.</p><p>If we are to open client.dll in IDA and use the "search for sequence of bytes" search method and input the that signature - We will see:</p><p><img loading="lazy" src="https://i.imgur.com/phkGjrn.png" class="img_ev3q"></p><p>This confirms that our signature is correct and will provide us with an address, but you might wonder how does this actually work? Look at this screenshot taken from IDA of the disassembly of that function:</p><p><img loading="lazy" src="https://i.imgur.com/nUPcsfF.png" class="img_ev3q"></p><p>Ignoring the actual disassembly, take a look at the numbers in grey on the left, these are the opcodes of the x86 assembly. What IDA as well as client.find_signature will do is scan memory for the pattern you provide it, until it matches completely and it will return the address in which the first match was found, which is why you must ensure that either there is only one match for your signature, or all the matches are completely identical.</p><p>So for example, we could do this in Lua as such:</p><div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token comment" style="color:#8292a2;font-style:italic">-- Specify the DLL that the signature is inside of, as well as handling an error if the signature wasn't found, this is always good practice.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> signature_match </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> client</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#9499ff">find_signature</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">"client.dll"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#95b806">"\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x64\x53\x56\x57\x8B\xF1\xE8"</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token keyword" style="color:#abd407">or</span><span class="token plain"> </span><span class="token function" style="color:#9499ff">error</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">"Signature was not found"</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- If everything went to plan, the address we now have in signature_match is a pointer to a function of type void(void*, float*).</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- This could also be done by using ffi.cdef, but global typedefs should be avoided.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> set_abs_angles </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> ffi</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#9499ff">cast</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">"void(__thiscall*)(void*, float*)"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> signature_match</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- You can now call set_abs_angles providing it with the correct arguments.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">...</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>A lot is used here, ffi.cdef and ffi.cast will be talked about in more detail soon.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="source-engines-interface-system">Source engine's interface system:<a class="hash-link" href="#source-engines-interface-system" title="Direct link to heading">​</a></h3><p>The Source Engine is comprised of many different DLL's that must interact with each other, to do this, the engine has a system called interfaces. Each DLL exposes a function to other modules called CreateInterface. What this allows other modules to do is call that function and give a specific interface name, and be provided with a pointer to that class, containing all the functions it needs. As you can imagine we can do this too as anyone can call these functions. The Lua API has provided us with a quick and easy way to do this, through client.create_interface. Interface names can be found by looking through the leaked CS:GO source code, specifically file names beginning with i such as <a href="https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/sp/src/public/istudiorender.h#L260" target="_blank" rel="noopener noreferrer">istudiorender.h</a>. Working with interfaces is arguably more complex than signatures, as the structure of abstract classes is a bit more complex. The structure is as follows:</p><div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token comment" style="color:#8292a2;font-style:italic">-- This ffi.cdef is put here purely for readability, still avoid using global typedefs, especially if you plan on having many users.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">ffi</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">cdef</span><span class="token string" style="color:#95b806">[[</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token string" style="color:#95b806">    typedef struct _our_interface {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token string" style="color:#95b806">        void** virtual_function_table;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token string" style="color:#95b806">    } our_interface;</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token string" style="color:#95b806">]]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> our_interface </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> ffi</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#9499ff">cast</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">"our_interface*"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> _client</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#9499ff">create_interface</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">...</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- If you look at the example interface I provided earlier in the Source SDK, you can see many function labelled virtual,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- these functions are stored as pointers in an array which is held in the first member of every interface, to access this</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- you can do what I have done and defined a helper struct to make accessing this easier, or cast it to something like</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- void** and dereference to get the address of this array.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> our_virtual_function_table </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> our_interface</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">virtual_function_table</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- I have defined the member virtual_function_table as void** because as I mentioned earlier, arrays are represented as pointers in memory,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- so we can access this list of functions like an array, and I have also made it an array of void*, as void* represents any pointer type.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- Lets say index 5 is a function pointer of type void(int) that we want to call.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">ffi</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#9499ff">cast</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">"void(*)(int)"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> our_virtual_function_table</span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token number" style="color:#ae81ff">5</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token number" style="color:#ae81ff">10</span><span class="token punctuation" style="color:#f8f8f2">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>@sapphyrus has just told be about some undocumented functions that the Lua API also provides to make virtual function table traversal easier,
vtable_bind and vtable_thunk can be used to quickly attach to a VFT which isn't directly exposed, and retrieve functions from it safely and quickly:</p><div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token comment" style="color:#8292a2;font-style:italic">-- Bind to the NetChannelInfo interface, which is retrieved from the GetNetChannelInfo function from the VEngineClient interface.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> native_GetNetChannelInfo </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token function" style="color:#9499ff">vtable_bind</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">"engine.dll"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#95b806">"VEngineClient014"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">78</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#95b806">"void*(__thiscall*)(void*)"</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- Generate thunks that will call the virtual function at the index provided, with the specified type.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> native_GetLatency </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token function" style="color:#9499ff">vtable_thunk</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token number" style="color:#ae81ff">9</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#95b806">"float(__thiscall*)(void*, int)"</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> native_GetAvgLatency </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token function" style="color:#9499ff">vtable_thunk</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token number" style="color:#ae81ff">10</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#95b806">"float(__thiscall*)(void*, int)"</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- Since GetLatency is a virtual function inside INetChannelInfo, pass the result of native_GetNetChannelInfo.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token function" style="color:#9499ff">native_GetLatency</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token function" style="color:#9499ff">native_GetNetChannelInfo</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">...</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">...</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="casting">Casting<a class="hash-link" href="#casting" title="Direct link to heading">​</a></h3><p>Casting is extremely useful and can be achieved through the ffi.cast function. I spoke briefly about casting earlier where I told the programming language that a number was actually meant to be interpreted as a pointer. This is the same in Lua, through the use of FFI, a number retrieved from client.find_signature or client.create_interface can be casted into a pointer value, allowing you to read and modify memory as you please. Some examples using ffi.cast are located below and throughout the rest of the post.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="some-examples">Some examples<a class="hash-link" href="#some-examples" title="Direct link to heading">​</a></h4><p>This example is taken from my Netvar Proxy hooking library, and it shows you how to call a function from an interface received from client.create_interface.</p><div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:rgba(0, 0, 0, 0.25)"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token comment" style="color:#8292a2;font-style:italic">-- Use client.create_interface to find the exported interface from client.dll</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> chl_client </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token function" style="color:#9499ff">cast</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">"void***"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> client</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#9499ff">create_interface</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">"client.dll"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#95b806">"VClient018"</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token keyword" style="color:#abd407">or</span><span class="token plain"> </span><span class="token function" style="color:#9499ff">error</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">'ChlClient is nil.'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- Dereference once to get the address of the VFT, which points to the first entry.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> chl_client_function_table </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> chl_client</span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token number" style="color:#ae81ff">0</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- Access index 8 into the function table as that is the index of the function I need.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> get_all_classes </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token function" style="color:#9499ff">cast</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">ffi</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#9499ff">typeof</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#95b806">"ntv_ClientClass*(__thiscall*)(void*)"</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> chl_client_function_table</span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token number" style="color:#ae81ff">8</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- When calling virtual functions, they will always require the first parameter to be the this pointer, which is just a pointer</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token comment" style="color:#8292a2;font-style:italic">-- To the class they belong to, like this.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#abd407">local</span><span class="token plain"> client_class </span><span class="token operator" style="color:#95b806">=</span><span class="token plain"> </span><span class="token function" style="color:#9499ff">get_all_classes</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">chl_client</span><span class="token punctuation" style="color:#f8f8f2">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Thank you for reading! I hope this helped you to get started with FFI and begin on your journey, I will be updating this post with examples and adding more sections in the future about more complex ideas and abstractions of memory that are commonly used in FFI development with GameSense such as safe pointers in Lua through FFI, as well as independent reverse engineering methods to help you keep yourself up to date, instead of relying on others. Stay tuned!</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a class="hash-link" href="#further-reading" title="Direct link to heading">​</a></h2><ul><li><a href="https://en.wikipedia.org/wiki/Typedef" target="_blank" rel="noopener noreferrer">C Typedefs</a></li><li><a href="https://luajit.org/ext_ffi.html" target="_blank" rel="noopener noreferrer">FFI Documentation</a></li><li><a href="https://luajit.org/ext_ffi_tutorial.html" target="_blank" rel="noopener noreferrer">Official FFI tutorial</a></li></ul>]]></content>
        <author>
            <name>owen</name>
            <uri>https://gamesense.pub/forums/profile.php?id=1598</uri>
        </author>
        <author>
            <name>sapphyrus</name>
            <uri>https://gamesense.pub/forums/profile.php?id=561</uri>
        </author>
        <category label="ffi" term="ffi"/>
        <category label="guide" term="guide"/>
    </entry>
</feed>