Brandon
2012-07-13 03:44:44
PROPER Location of Text Rendering coming soon (HOPEFULLY). VertexBuffer Hook coming soon (HOPEFULLY). This will allow me to grab the actual vertices rather than vertex #0. That way I can click objects even if only 1 pixel of it is showing. Atm, it clicks dead center of an object unless you specify the offset vertex.
I plan to use Base 36 for ID's to shorten them. Well maybe only on the Simba side. Probably leave it as Base 10 on the C++ side.
https://github.com/Brandon-T/GLHook
While reading below, you'll realize I said I have trouble with Triangle Enumeration and 3D Programming math.. This is an updated Edit: http://www.arcsynthesis.org/gltut/Basics/Introduction.html
That's where I'm learning the math to build on this foundation.. I already know calculus and stuff but this is some next level crap.
Note: The github only contains the basic layout.. It doesn't contain the most updated version so it doesn't reflect how far I got but meh that's ok for now.
I guess now is about the right time to tell the world I was working on the OpenGL hooking.. Since SRL is down, everyone is looking at alternatives and I guess I'll start showing one too. Mato has DirectX I have OpenGL. I'm not taking anything away from him. He is a brilliant fellow and I hope he continues without rushing. I may or may not finish or continue this but here is a brief explanation of how the shit works right now.
First I used "DLLExport Viewer x64" to figure out what Jagex's OGL has compared to the one in my System32/SysWOW64.
They use a library/DLL called Corona for imaging, etc.. I saved a list of all exported functions from Jagex's DLL and with the same program saved a list with the one on my system. With a little reading I learned to Detour Functions and Inject by writing to process memory. Both of which I provided in the GitLink.
A detour function is a function that has the exact same syntax as the original function. Aka the one we are trying to hook.
So lets say OpenGL.dll has one that looks like: void glBegin(GLEnum mode);
Our Detour would look like GLHook_glBegin(GLEnum mode);
Now what does that have to do with anything.. well here is some sample code:
GLHook_glBegin(GLEnum mode)
{
//Do whatever we want in here.. then below, we pass the parameters to the original function.
(*optr_glBegin(mode);
}
In our detour, we are getting the client's data FIRST! Then we pass it to the OpenGL32.dll in our system folder. That *optr_glBegin is a function pointer to the original OpenGL32.dll in sys32.
Now that that's clear, the next thing I did was learn what each function does. I did this by reading through the entire MSDN database on OpenGL functions :c Yes I know.. a lot of reading and shit.
When I saw how many functions there were to write, I gave up and wrote function generator which looks like:
//#define _WIN32_WINNT 0x0403
#include <windows.h>
#include <iostream>
#include "Functions.hpp"
#include "Strings.hpp"
using namespace std;
StringArray GLTypes = StringArray("GLint ", "GLuint ", "GLenum ", "GLfloat ", "GLclampf ",
"GLsizei ", "GLboolean ", "GLubyte ", "GLvoid ", "const ",
"GLbitfield ", "GLclampd ", "GLdouble ", "GLshort ", "GLbyte",
"GLushort ", "GLclampi ", "GLbitfield ", "void", "HDC ", "DWORD ",
"LPGLYPHMETRICSFLOAT ", "FLOAT ", "DOUBLE ", "UINT", "INT ", "float ",
"double ", "int ", "LPCSTR ", "LPSTR ", "LPTSTR ", "LPCTSTR ", "LPLAYERPLANEDESCRIPTOR ",
"LPPIXELFORMATDESCRIPTOR", "PIXELFORMATDESCRIPTOR ", "HGLRC ", "COLORREF ", "BOOL ", "*",
"**");
void CreateGLFunctionsFromTypedefs()
{
StringArray FileContents;
ifstream File("C:/Users/Brandon/Desktop/OGL Editing/GLTypedefs.hpp", std::ios::in);
if (File.is_open())
{
string Line;
while (getline(File, Line))
FileContents(Line);
File.close();
}
string Temp = string();
string FuncType = string();
string PtrStr = string();
string Final = string();
ReplacementFlags FalseFlags = ReplacementFlags(false, false);
for (size_t I = 0; I < FileContents.Size(); I++)
{
if ((FileContents[I][0] == 't') && (FileContents[I][1] == 'y'))
{
FuncType = Copy(FileContents[I], 9, Pos("(WINAPI", FileContents[I], 9) - 9);
Temp = Replace(FileContents[I], "typedef ", "", FalseFlags);
Temp = Replace(Temp, "(WINAPI *ptr_", "", FalseFlags);
PtrStr = Replace(Temp, ";", "", FalseFlags);
PtrStr = Copy(PtrStr, Pos(" ", PtrStr, 0) + 2, PtrStr.end() - (PtrStr.begin() + Pos(" ", PtrStr, 0)) + 2);
Temp = Replace(Temp, ";", "\n{\n\t", FalseFlags);
Temp = Replace(Temp, ") (", "(", FalseFlags);
PtrStr = ((FuncType[0] == 'c' && FuncType[1] == 'o') && (PtrStr[0] == 'G' && PtrStr[1] == 'L')) ? Copy(PtrStr, Pos(" ", PtrStr, 0) + 2, PtrStr.end() - PtrStr.begin() - 2) : PtrStr;
Temp = (FuncType[0] == 'c' && FuncType[1] == 'o') ? Replace(Temp, " gl", " GLHook_gl", FalseFlags) : Replace(Temp, " ", " GLHook_", FalseFlags);
Temp = "GL_EXPORT __stdcall " + Temp; //__stdcall added.
for (size_t J = 0; J < GLTypes.Size(); J++)
{
PtrStr = Replace(PtrStr, GLTypes[J], "", ReplacementFlags(true, false));
PtrStr = Replace(PtrStr, "*params", "params", ReplacementFlags(true, false));
}
PtrStr = "(*optr_" + PtrStr + ";";
PtrStr = ((FuncType != "void") ? "return " : "") + PtrStr;
Temp += PtrStr + "\n}\n\n";
Final += Temp;
}
}
WriteFile("C:/Users/Brandon/Desktop/OGL Editing/GLFunctions.hpp", Final);
}
void CreateGLAddressesFromDefinitions()
{
StringArray FileContents;
ifstream File("C:/Users/Brandon/Desktop/OGL Editing/GLHook.def", std::ios::in);
if (File.is_open())
{
string Line;
while (getline(File, Line))
FileContents(Line);
File.close();
}
string Final = string();
for (size_t I = 0; I < FileContents.Size(); I++)
{
if ((FileContents[I][0] != ';' ) && (Pos("LIBRARY", FileContents[I], 0) == -1) && (Pos("DESCRIPTION", FileContents[I], 0) == -1) && (Pos("EXPORTS", FileContents[I], 0) == -1))
{
StringArray Split = SplitString(FileContents[I], "= ");
for (size_t J = 0; J < Split.Size(); J++)
{
//if (Split[J][0] != 'G' && Split[J][1] != 'L' && Split[J][2] != 'H' && Split[J][3] != 'O' && Split[J][4] != 'O' && Split[J][5] != 'K')
if (Pos("GLHook", Split[J], 0) == -1)
{
//Final += "MessageBox(NULL, \"" + Split[J] + "\", \"CrashReport\", 0);\n";
Final += "if ((optr_" + Split[J] + " = (ptr_" + Split[J] + ") GetProcAddress(OriginalGL, \"" + Split[J];
Final += "\")) == NULL)\n{\n\treturn false;\n}\n\n";
//Final += "\")) == NULL)\n{\n\t";
//Final += "MessageBox(NULL, \"" + Split[J] + "\", \"CrashReport\", 0);\n\t";
//Final += "return false;\n}\n\n";
}
}
}
}
WriteFile("C:/Users/Brandon/Desktop/OGL Editing/GLProcAddresses.hpp", Final);
}
void CreateGLExternsFromTypedefs()
{
StringArray FileContents;
ifstream File("C:/Users/Brandon/Desktop/OGL Editing/GLTypedefs.hpp", std::ios::in);
if (File.is_open())
{
string Line;
while (getline(File, Line))
FileContents(Line);
File.close();
}
string Temp = string();
string Final = string();
for (size_t I = 0; I < FileContents.Size(); I++)
{
int Position = Pos("*ptr_", FileContents[I], 0) + 5;
if (FileContents[I][0] == 't' && FileContents[I][1] == 'y')
{
Temp = Copy(FileContents[I], Position + 1, Pos(") ", FileContents[I], Position) - Position);
Final += "extern ptr_" + Pad(Temp, 27, " ", false) + "optr_" + Temp + ";\n";
}
else
{
Final += FileContents[I] + "\n";
Final = Replace(Final, "TYPEDEFS", "NAMING", ReplacementFlags(false, false));
}
}
WriteFile("C:/Users/Brandon/Desktop/OGL Editing/GLExterns.hpp", Final);
}
void CreateGLDefinitionsFromTypedefs()
{
StringArray FileContents;
ifstream File("C:/Users/Brandon/Desktop/OGL Editing/GLTypedefs.hpp", std::ios::in);
if (File.is_open())
{
string Line;
while (getline(File, Line))
FileContents(Line);
File.close();
}
string Temp = string();
string Final = string();
Final += "; @Author : Brandon T.\n";
Final += ";\n";
Final += "; @param : GLHook Definition File.\n";
Final += "; @param : Info From MSDN Documentation.\n\n\n";
Final += "LIBRARY GLHook\n";
Final += "DESCRIPTION \"GLHook Definition File\"\n";
Final += "EXPORTS\n\n";
for (size_t I = 0; I < FileContents.Size(); I++)
{
int Position = Pos("*ptr_", FileContents[I], 0) + 5;
if (FileContents[I][0] == 't' && FileContents[I][1] == 'y')
{
Temp = Copy(FileContents[I], Position + 1, Pos(") ", FileContents[I], Position) - Position);
Final += Pad(Temp, 27, " ", false) + "= GLHook_" + Temp + ";\n";
}
}
WriteFile("C:/Users/Brandon/Desktop/OGL Editing/GLHook.def", Final);
}
void CreateGLNamingListFromExterns()
{
StringArray FileContents;
ifstream File("C:/Users/Brandon/Desktop/OGL Editing/GLExterns.hpp", std::ios::in);
if (File.is_open())
{
string Line;
while (getline(File, Line))
FileContents(Line);
File.close();
}
string Final = string();
for (size_t I = 0; I < FileContents.Size(); I++)
{
if (FileContents[I][0] == 'e')
Final += Replace(FileContents[I], "extern ", "", ReplacementFlags(false, false)) + "\n";
}
WriteFile("C:/Users/Brandon/Desktop/OGL Editing/GLNamingList.hpp", Final);
}
void GLCompare()
{
string ListOfGLExports = ReadFile("C:/Users/Brandon/Desktop/ListOfGLExports.hpp", false);
string CurrentExports = ReadFile("C:/Users/Brandon/Desktop/CurrentExports.hpp", false);
StringArray ListOfGLExportsSplit = SplitString(ListOfGLExports, "\n");
StringArray CurrentExportsSplit = SplitString(CurrentExports, "\n");
string Temp = string();
string Final = string();
for (size_t I = 0; I < ListOfGLExportsSplit.Size(); I++)
{
if (Pos(ListOfGLExportsSplit[I], CurrentExports, 0) == -1)
{
cout<<ListOfGLExportsSplit[I]<<endl;
}
}
}
int main(int argc, char* argv[])
{
StreamFlags(std::cout);
CreateGLFunctionsFromTypedefs();
CreateGLExternsFromTypedefs();
CreateGLDefinitionsFromTypedefs();
CreateGLAddressesFromDefinitions();
CreateGLNamingListFromExterns();
//GLCompare();
cin.get();
return 0;
}
What the above does, is generate a list of ALL OpenGL functions, its externs, its Definitions, its Detours, and its Address Procs. It uses a library I wrote myself called Purely-CPlusPlus. I posted it on SRL about last week when it got no attention so I removed it :c
To do it manually is a waste of time! Trust me! it's a total of 6000 lines of code being generated. Not including the undocumented ones which I decided to remove.
From that code, put it all into a DLL Module and LoadRS. RS Will load your DLL first which will in turn load the original OpenGL but instead of RS passing commands to the original, it will pass it to yours which will read it and log it and then pass it to the original. Thus we can modify calls, log them, do whatever with them, and as such, create wireframes which look like:

Edit: Item Recognition is Ok.. Algorithm is still shit.



Edit 2:
I'm getting close and close to model recognition. Don't have an algorithm for ID's yet. I believe I can actually store a list of vertices due to the way I wrote the model code. I stored the vertex pointer's pointer. I get the index count and divide by 3 for triangle count. Iterate the pointer for each triangle and store the vertex (THEORETICAL. It should work though.. I hope). At the time of posting the following pictures, I store only the first vertex and offset the Y by 213 (50 for the bar).



EDIT3: Grabbing Texts are working.. Positions are off but I THINK I can fix that (What I have in mind is theoretical, Heavy use of matrices ={ ).. Also as you can see, it renders shadows too so I've provided parameters to the function to specify whether the text we want should have a shadow or not. I have to fix positions first though.



Now it's up to you guys to do stuff with the logs OR teach me the math required to generate ID's out of those models above or throw some ideas out there for whoever decides to pick this shit up if I leave or whatever.. Now I have to learn the math required to generate ID's. Yes I did a bit of hacking and all that crap before but this math is OpenGL math.. It's not the same :c. Math with depth, height, width, view, etc.. I did calculus but i'm not sure if that is enough. So you guys pitch in where you can. Try to learn OpenGL too. It took me a total of 6 days to get this far. 2 Days of trial and error and testing and crashes due to jagex's bs and the fact that my generator messed up a couple functions (though that is fixed now). With a little CPP background, OGL won't take long to catch on.. The github is 4 days old but it took me 6 to get this far. I don't know how far I can push this project so everyone needs to learn it and pitch in. That goes for directX too. I'll help mato wherever I can.
P.S. I was asked to show u guys this. I actually wasn't going to show anything just yet because questions will hit me left right and center like OMG when is ETA and all that stuff such as the ones seen on Mato's thread.























