Finding Virtual Offsets

On viernes, 9 de septiembre de 2011 1 comentarios

Introduction

Finding virtual offsets provides us a way to access functions in the games that we otherwise would not be able access. Using either SDKCalls, Extensions, or MM:S Plugins, we can make use of these virtual offsets to give us a massive amount of functionality that is not included with Sourcemod out of the box.
For this example, you will need a copy of IDA Disassembler. We will be using IDA Pro 5.2 but any of the more recent versions should work fine (will not work with the free version). You will also need to grab this linux_vtable_dump.idc file and install it into your IDA/idc/ directory. Lastly, you will need to get a copy of the Linux server file for the game you want to find the offsets for. This will generally be in the 'bin' directory of your game folder and the file will be named server.so (use server_i486.so for older games that do not have server.so) along with some other similar files.

Finding Offsets

Disassemble the Linux Server:
Now that your files are setup appropriately, you can start the IDA Disassembler. On the Welcome to IDA box that opens initially, you will want to click the "New" button. This will allow us to add a new file for it to disassemble. After you initially disassemble the file, you will be able to reload it without any hassle by using the 'Previous' button and selecting the file on this screen.

Image:Ida welcomescreen.png

After you click the New Button, the application will open. It will prompt you to choose a specific type of file from a box, however you can just close this as we do not need it. The screen should now say "Drag a File Here to disassemble". Open your folder containing the server_i486.so and drag drop this file in now. This will start the disassembling process, and depending on hardware, can take anywhere from 15-30 minutes to completely finish.

Find the Virtual Table::
You will want to be in IDA View-A and make sure you can see both the IDA View-A window as well as the Names window to make this easier on yourself. For this example, we will be finding the Virtual Offset for the function CBasePlayer::ChangeTeam. Our first step is to locate this function in the Names window. (The search hotkey combination is Alt+T) Now once you find this function, in the Names window, double click it, and it should select a line in the IDA View-A window that looks something similar to this.

Image:Ida changeteamscreen.png

From here we are going to want to go to the Jump Menu up top, and select Jump to Cross Reference. (The hotkey is CTRL+X) This will find the reference files for this paticular function. You will want to make sure that you find the line with `vtable at the start of it, as this will be the Virtual Table file that contains the offsets for us.

Image:Ida crossjump.png

Save the Virtual Table file::
Now double click the line that says `vtable for'CBasePlayer and you will be brought back to the IDA View-A window. This time your cursor will be on the line with the VTable information. You have now successfully located the file you need, and you are ready to get the offsets. Making sure that your cursor is still somewhere in that line, go to...
File -> IDC File
and browse to the linux_vtable_dump.idc file that we placed in the IDA directory earlier. Load this file and click OK, and it will now ask you to enter a number for VTable's entries to ingore indexing. Setting this to 0 will output a file listing the exact Linux offsets, setting this to 1 will output a file which estimates the windows offsets (general rule is windows offset = linux offset - 1 but this isn't always the case). It will run your IDC script file, and give you another dialog box. This time it wants you to choose the location for the dump file. Browse to your desktop, and enter anything for the File Name box, and click Save. You now have a text file on your desktop will all of the CBaseEntity offsets inside of it that you can use.

Conclusion

That is all there is to it. Keep in mind that even though this is the Linux server file, the offsets listed in the dump file are for windows. You will just need to add +1 to these offsets to obtain the Linux offset. Make sure that you are using the Linux server file when you disassemble as well, because the Windows server does not have symbols or readable names, and you will not be able to find the offsets with it (unless you have the .pdb files for it, which only the Developers of the Game / Mod should have).

Windows Info

[07:38pm]  dvander word it in such a way that I can copy/paste it into the wiki
[07:38pm]  lol, i dunno if i can do that in IRC.  basically, there are two tricks
[07:39pm]  the first is if you know assembly really well
[07:39pm]  you can look at the SDK for a function that calls something you are interested in
[07:39pm]  find a string in that function, or a string in a function in its cross-reference graph
[07:40pm]  for the former case, find the same string in the windows binary and use the xref graph to find the right function
[07:40pm]  for the latter case, say a function with a string in it calls the function that has what you want
[07:40pm]  you find the first function, then read through it until you get to what you want
[07:41pm]  once you have the actual function you're looking for
[07:41pm]  you use the xref graph to find its reference in the data section
[07:41pm]  it will be in a large table - the virtual table
[07:41pm]  and you can compute its offset from the base of that table
[07:42pm]  the other trick is a bit easier, sometimes
[07:42pm]  you compile the SDK on windows
[07:42pm]  turn on the MSVC feature that dumps assembly
[07:42pm]  and poke around, using educated guessing
Read more ...»

C++: Insertar un ejecutable dentro de otro… y luego ejecutarlo

On jueves, 8 de septiembre de 2011 4 comentarios

C++: Insertar un ejecutable dentro de otro… y luego ejecutarlo

Vamos a explicar cómo tomar un ejecutable (o cualquier otro fichero binario), insertarlo dentro de un ejecutable y posteriormente cómo recuperar ese ejecutable embebido, soltarlo a disco y ejecutarlo. El escenario típico es borrar el propio ejecutable que actúa como hospedante, pero seguro que a las mentes calenturientas de mis lectores se les ocurren más aplicaciones.
El problema no existía en Windows 95 y siguientes: un programa podía borrar su propio ejecutable y terminar sin ningún problema (o casi). Pero en los núcleos NT hacer eso es harina de otro costal. Teóricamente se puede hacer mientras que el ejecutable a borrar no abra ningún handle… pero evidentemente cualquier ejecutable suele abrir no uno, sino infinidad de ellos.
La solución consiste entonces en disponer de dos ejecutables en disco. El primero hará su tarea y llamará al segundo antes de terminar, que tras unos instantes procederá a borrar el primero, quedando éste último en disco. Pero entonces tenemos que distribuir dos ficheros y colocarlos en el mismo sitio, por lo que la mejor solución es que el primero contenga al segundo en sus entrañas y lo use a voluntad. Incidentalmente el segundo podría decir a Windows que lo borre en el siguiente reinicio, pero no vamos a entrar en detalles sobre esto.
Primer paso: Insertar el ejecutable
Suponiendo que tengamos ya construido nuestro ejecutable (que vamos a llamar “borra.exe”), insertar un recurso del tipo RCDATA en un fichero ejecutable es una tarea trivial. Basta con abrir el fichero de recursos del ejecutable (el .rc) como texto e insertar la línea:
ELEXE RCDATA "..\\final\\Win32\\Release\\borra.exe"
Recompilamos y ya tenemos el ejecutable como recurso binario embebido en nuestro propio ejecutable. Evidentemente no estamos limitados a ningún tipo de archivo en concreto. Podríamos hacerlo incluso con recursos normales (mapas de bits, iconos, cadenas, etc.). La única diferencia es la forma de recuperar un recurso binario de uno almacenado como estándar.
Segundo paso: Sacar el ejecutable y ponerlo en disco
Cuando queramos volcar nuestro ejecutable a disco, debemos ejecutar algo parecido a lo siguiente:
HRSRC res=FindResource(NULL,_T("ELEXE"),RT_RCDATA);
if(res==NULL)
     return GetLastError();

int size=SizeofResource(NULL,res);
HGLOBAL hRes=LoadResource(NULL,res);
unsigned char *pRes=(unsigned char *)LockResource(hRes);

HANDLE hFile=CreateFile(szT2Path,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
if(hFile==INVALID_HANDLE_VALUE)
     return GetLastError();

WriteFile(hFile,pRes,size,&bytesWritten,NULL);
CloseHandle(hFile);

ShellExecute(HWND_DESKTOP,NULL,szT2Path,NULL,NULL,SW_SHOWNORMAL);
El primer paso consiste en llamar a FindResource con el nombre y el tipo de recurso. Si nuestro fichero hubiera estado almacenado en otro lugar que no fuera nuestro propio ejecutable, el primer parámetro a pasar es la instancia del fichero externo.
Tras tener un handle válido, tenemos que mirar el tamaño que ocupa el recurso almacenado, lo que hacemos con SizeofResource.
Ahora viene cargar el recurso en memoria y obtener un handle de memoria (LoadResource). Pero todavía no podemos acceder a los bytes de nuestro fichero, debemos bloquear el acceso a los mismos mediante LockResource, lo que nos devolverá un área de memoria accesible.
Aquí el autor lo ha asignado a un buffer de caracteres sin signo, pero realmente cualquier tipo de dato es perfectamente válido, aunque tenemos que tener en cuenta de no guardar ningún byte de más en el fichero final. Haciéndolo con un buffer de caracteres nos aseguramos de guardar el tamaño correcto.
Ya solo nos queda guardar el buffer a disco y hacer la llamada para ejecutar el fichero extraído.
Quizás nos preguntemos por qué no hemos liberado la memoria apuntada por pRes: está expresamente descrito en la documentación de la MSDN: no debemos hacerlo nosotros, ya lo hará el sistema cuando corresponda.
Consideraciones finales
Evidentemente una solución más sencilla sería marcar el propio ejecutable para ser borrado en el siguiente reinicio en lugar de hacer toda esta parafernalia, pero a veces puede no interesarnos que dicho fichero esté en disco hasta ese momento.
De todos modos aplicaciones para esto las hay a montones. Soltar un ejecutable que haga algo, termine y luego sea borrado por el programa principal, forzar un reinicio del programa principal, distribuir un solo exe que luego suelte todos los ficheros que necesite…

Origen: http://geeks.ms/blogs/rfog/archive/2008/09/11/c-insertar-un-ejecutable-dentro-de-otro-y-luego-ejecutarlo.aspx
Read more ...»

Dota 2 Gamescom Trailer

On 0 comentarios

What does a hero truly need?

Find out when the world's best players compete in the first ever Dota2 professional tournament August 17th - 21st at Gamescom in Cologne, Germany. Watch live streaming games and replays at Dota2.com.

Visit Steam to download the 1080p HD version of the trailer.

Read more ...»