Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Part 3: The Nitty Gritty ~
- At the core of exploiting knowledge is an understanding of the inner workings of the program you are trying to hack. Whether you're just starting out or you're a master at the hobby, the more knowledge you have, the more power you have. In a game of chess, the first step to figuring out the best move is actually knowing the rules of chess. In the game of exploiting, the first step to figuring out the best solution is actually knowing the workings of the ROBLOX player. Lots of people miss that for some reason, and all of the new users you see around V3rmillion are trying to make their moves without knowing how to play.
- This chapter is devoted to making sure that you know the rules of the game before you start playing. By the end of this part, you should understand all the concepts you need for the path we're taking (DLL injection, C++ pointers, and memory math), and you should have a blank slate that is ready to be molded into your very first exploit.
- [Image: KQUJY8x.gif]
- ~ DLL Injection ~
- Most exploits involve modifying the game or forcing it to run code through any means necessary. The easiest way to do this is DLL injection. As explained in an earlier chapter, a DLL is a Dynamic Link Library, designed to be used and included by programs. Forcing a program to execute a DLL is called DLL injection. Windows will start the DLL at its entry point, and the program won't know anything is wrong. The DLL will act as code inside the program it was injected into; it will be able to access anything the program can.
- There are many DLL injectors available online. The most common one used on V3rmillion is called Extreme Injector, but I personally think that the best solution is to implement your own. The actual procedure of DLL injection is pretty hard to understand for somebody who is just starting out with this kind of programming. I don't even fully understand it. So if you do this, I encourage you to look up the C++ source of a DLL injector (although if you're interested, by all means, put some effort into understanding it) and modify it to suit your needs.
- Before using our DLL injector, we need a DLL to inject. That will be the entirety of our exploit. We can write a DLL in C++, complete with everything that we need to do our magical hacks. Open Visual Studio (or whatever IDE you are using) and create a new empty C++ project.
- [Image: cSf29k.png]
- Once the project is created, right click on "Source Files" in the solution explorer. Hover over "Add" and select "New Item..." In the menu that comes up, select "C++ File (.cpp)" and add it to your program. Name it something relevant (I named mine "main.cpp"). The new file should open up in your editor.
- Before we begin working on the code though, we need to specify that we are creating a DLL file. So right click on your project (your project, not your solution - your project should be directly inside of your solution) and click "Properties" at the bottom. Expand "Configuration Properties" and select "General." Scroll down to Project Defaults, and change the Configuration Type from "Application (.exe") to "Dynamic Library (.dll)."
- [Image: eqn5sS.png]
- Click "OK" or "Apply" and all of the relevant settings will be magically updated, enabling your program to be compiled as a DLL.
- Next, create the entry point of your DLL. This is where the code will begin running when ROBLOX is forced to execute it. Paste the following code into main.cpp:
- Code:
- #include "windows.h"
- BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
- if (fdwReason == DLL_PROCESS_ATTACH) {
- // Our exploit code will begin here
- }
- return 1;
- }
- This code will run immediately when the process is attached. To make sure we have everything set up corretly, first find the drop-down that says "Debug" and change it to "Release" (we have no use for a debug build when writing a simple exploit, it will simply make our exploit easier to reverse engineer). Then click the "Build" drop-down menu and select "Build Solution" (or press F7) and watch the output. The final line should show 1 file as succeeded, and none as failed, up-to-date, or skipped. Otherwise, go back and make sure you did everything right.
- If the DLL compiled successfully, you will find it in Visual Studio\Projects\Your Exploit Name\Release. It will be named after your project. If at any point you have a finished release of your DLL file, simply copy it somewhere and rename it to whatever you'd like. All compiled builds of your exploit will end up in the Release folder and will overwrite any previous one.
- [Image: yMDEkm.png]
- You now know how to build a DLL file. Congratulations! If you inject it, nothing will happen. That is because we haven't written any code yet. But we will come back to that next time. For now, we're going to do some learning about the powerful concepts you're going to be using in your code.
- [Image: KQUJY8x.gif]
- ~ Hexadecimal Numbers ~
- You may have read that title and cringed a little bit. You're probably thinking, "NUMBERS?!? Autumn, are you my math teacher now or something!?" And the answer to that question is yes. Hexadecimal numbers are very commonly used in low-level and memory-related programming. Understanding hexadecimal is an absolute must for an exploiter. So let's get right into it!
- The number system we use on a daily basis as humans is called decimal. There are 10 numbers in decimal (hence the "deci- prefix"), and every single number in existence is made up of a combination of those 10 numbers. They range from 0 to 9. When you reach the highest number, you simply set it back to zero, add a number to the left of it, and count up to the maximum all over again. This goes on forever. If you passed kindergarten, I'm sure you don't need me to explain any further.
- Hexadecimal works exactly the same as decimal, with the only exception being that there are 16 numbers that all numbers are made up of instead of 10. In hexadecimal, the highest number isn't 9, it's F. Once you pass 9, you start counting in the alphabet: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. When you pass F, you simply reset it to 0, add a number to the left, and count up all over again, just like what we're used to.
- This means 10 in hex is 16 in decimal. The number that comes after 9 in hex is A, so that means A in hex is 10 in decimal. It can be very hard to figure out these things in your head, but simply understanding how it works is good enough. You can find all sorts of calculators online that translate decimal to hexadecimal. Google one and bookmark it!
- So now that we covered what hexadecimal numbers are, what are C++ pointers? Well, remember when we were poking through IDA Pro to find Lua C functions? Most of the numbers we saw in that program are actually displayed in hexadecimal. It's the number system of machines (for some reason, software engineers everywhere insist that, and exploiters like us have to deal with it).
- [Image: k8AoVg.png]
- Those numbers in that IDA screenshot are actually memory addresses. As the program runs, its little allocated pool of memory can store all kinds of different values, and each has its own address. That address represents the specific area of memory where the value is stored. Those addresses are normally represented in hexadecimal, which is important to note when doing any sort of math related to them. You might be wondering, why would you need to do math to them in the first place?
- [Image: KQUJY8x.gif]
- ~ C++ Pointers ~
- Pointers, that's why! C++ has an amazing feature called pointers. It is one of the main things that separates C/C++ from any other language in existence, and it's also the reason we use C/C++ for exploiting. Whenever you store a variable in any language, the value is stored in some memory location, and its address is handled behind the scenes by the language itself. In C++, you have the option to take that into your own hands. Pointers allow you to take a number, tell C++ "trust me, there is a value in the program memory under this address," then pull out the value and do whatever you want with it. It also allows you to set any area of memory to any value you want!
- This is amazing, but also easy to mess up. When you are using pointers, you are taking things into your own hands. You are taking a fundamental concept that is normally done for you and doing it manually. It's like opening up a computer and messing with the components by yourself. This means if something goes wrong, it really goes wrong. The only thing you'll have to work with is some type of crash. Maybe it froze, maybe a weird message popped up and it closed, or maybe your computer got a BSOD. There is no way to know! So make sure to be extra careful and attentive.
- We will go over pointers a lot more when we begin writing the exploit. For now, take a look at this very basic hypothetical example. Imagine the number 1337 is stored in memory, and its address is C0FFEE in hex. We know that it is an int value. C++ doesn't know any of these things, but we do. So we can be its guide.
- First of all, a pointer is a very special type of value. If we wanted to create an int pointer, we would need to use the * operator, which tells C++ that it's the memory address of an integer. It has no way of knowing what the value type is; all it sees is the raw data. By telling C++ that a pointer is an int pointer, it knows to interpret that raw data as an int.
- Code:
- int* leetPtr;
- Since it's a pointer, it needs to be set to a memory address. We know the address is C0FFEE, so we need to specify that. In C++, we prefix a number with 0x to specify that it's supposed to be hexadecimal. So C0FFEE in C++ syntax would be 0xC0FFEE:
- Code:
- leetPtr = (int*)0xC0FFEE;
- Notice how we casted 0xC0FEE to an int*. C++ will see it as an int by default, and since a pointer is a different type of value, we need to use typecasting. We can shorten the above two lines into this single one:
- Code:
- int* leetPtr = (int*)0xC0FFEE;
- Next it's time to dereference the pointer. Dereferencing is a fancy name for pulling the value out of that memory address. To dereference a pointer, you use the same * operator, but you put it before the value instead of after its type. Now we could, of course, just print it out like this:
- Code:
- cout << leetPtr << endl;
- cout << *leetPtr << endl;
- That would first print the memory address (leetPtr itself), then on the next line, it would dereference leetPtr and output the number 1337 (assuming 1337 was really an int stored in that memory address). But that's boring. We want to store it for later use. Since it's an int pointer, and we know the value stored there is an int, we can use an int variable:
- Code:
- int leet = *leetPtr;
- Tada! The leet variable now contains 1337. Pulled straight from the memory like magic.
- Now that we know how this works, everything above can actually be shortened to this:
- Code:
- int leet = *(int*)0xC0FFEE;
- That line casts 0xC0FFEE to an int pointer, immediately dereferences it, then sets the result to a brand new int value called leet. If 1337 is stored at 0xC0FFEE, the leet varaible will be set to the number 1337. Simple!
- Last but not least, take a look at what we can do if we dislike the number 1337:
- Code:
- int* leetPtr = (int*)0xC0FFEE;
- *leetPtr = 5;
- int leet = *leetPtr;
- cout << leet << endl; // Output: 5
- I'll let the implications of this sink in Tongue
- Don't go trying to do anything memory-related with ROBLOX yet, because there are a few more things to cover in the next tutorial, such as ASLR and some anticheat measures. But I hope this prepares you fully for everything there is to come!
- [Image: KQUJY8x.gif]
- ~ In the Next Guide ~
- In part 4 of a Lua scripter's guide to ROBLOX exploiting, we will open up that C++ DLL project and begin coding. We will use IDA Pro, hex numbers, and pointers. We will learn about the different anti-exploiting checks ROBLOX has in place and the different hypothetical ways of getting around them. We will learn about ASLR, and how to find/change values in a program that uses it. And lastly, we will be learning about the typedef keyword, and how it can be used with pointers to teach C++ how to call functions that exist inside a program's memory.
- See you then! Tongue
- Click This: http://www.lua.org/
Add Comment
Please, Sign In to add comment