Archive

Archive for the ‘C’ Category

Small pseudo-assembler interpreter

August 30th, 2009 Wesley 2 comments

I had to develop a pseudo-assembler interpreter for the course Microprocessing.

Since it was just lying around on my hard drive I figured I could just as well put it on-line. It contains a few things that might be interesting to developers:

  • Using a C library in C++/Qt applications and translating C function callbacks into Qt signals
  • Implementation of virtual static and virtual dynamic memory
  • Converting between virtual signed and unsigned values (system independent)
  • Saving data and instructions in same virtual memory (Von Neumann architecture)

More information (and source code) is available here: http://wesley.vidiqatch.org/files/qpasm/

VN:F [1.6.3_896]
Rating: +2 (from 2 votes)
Categories: C, C++, Open Source, Programming, Qt, School

Overriding dynamic library calls (function interposition)

August 18th, 2009 Wesley 7 comments

About function interposition

I was wondering how I could override dynamic library calls in Linux, and I came across this technique known as function interposition. It is a powerful technique that allows you to override dynamic library calls. It might sound dull, but it can be very, very useful. There are some memory trace tools that make use of this technique to work, but perhaps a cooler example is the OpenGL capture system which was created by nullkey: it can capture OpenGL frames by overriding certain OpenGL functions. Another example are cheat tools (wallhacks, aimbots) which also make use of this technique a lot.

Some background

While Googling (did I spell that right?) I came across this recent blog article which explains the background very well. I will quote it here:

First, some background. When a program that uses dynamic libraries is compiled, a list of undefined symbols is included in the binary, along with a list of libraries the program is linked with. There is no correspondence between the symbols and the libraries; the two lists just tell the loader which libraries to load and which symbols need to be resolved. At runtime, each symbol is resolved using the first library that provides it. This means that if we can get a library containing our wrapper functions to load before other libraries, the undefined symbols in the program will be resolved to our wrappers instead of the real functions.

So if we create a custom shared library which overrides some of the functions of the original library, our functions will be called instead of those of the original library.

How to do it

  • Write new functions which override existing functions
  • Compile the written code to a dynamic library that is linked to the dynamic linking interface library
  • Use the LD_PRELOAD environment variable when running an application to preload your custom library before all other dynamic libraries

The article by Jay Conrod has an example which shows you the basic implementation of a simple memory allocation tracer.

I have also cooked up an example myself. Because I’ve been busy learning more about OpenGL, I thought that it shouldn’t be too hard to create a wallhack for one of my favourite games: Soldier of Fortune 2 running in Wine. Just for testing purposes of course! I am no cheater :D It turned out to be relatively simple, although my first tries weren’t so very successful:

  • Epic fail – At least I know my library is used now.
  • Partial success – Disabling depth testing completely was only a partial success.
  • Success – A debugger can tell that players are drawn using glDrawElements(). By knowing the number of elements for each character, we can disable depth testing selectively.
Soldier of Fortune 2 wallhack example

Soldier of Fortune 2 wallhack example

For those of you who are interested in the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
    Simple wallhack example for Soldier of Fortune 2 (Wine) in Linux using function interposition

    This code snippet was written by Wesley Stessens (wesley@ubuntu.com)
    It is released in the Public Domain.

    Compilation: gcc -Wall -ansi -pedantic -shared -ldl -fPIC glhack.c -o glhack.so
    Usage: LD_PRELOAD=glhack.so wine game.exe
*/


#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdint.h>
#include <GL/gl.h>

/* Override the glDrawElements function */
GLAPI void GLAPIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
    /* Store the actual function in a static function pointer */
    static void (*glDrawElements_)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) = NULL;
    if (!glDrawElements_) {
        glDrawElements_ = (void(*)())(intptr_t)dlsym(RTLD_NEXT, "glDrawElements");
        puts("GLHack: glDrawElements call has been overridden");
    }

    /* Disable depth testing if the number of elements to draw is one of the following, which means a player is being drawn */
    /* To avoid abuse of this code by cheaters, I have changed all count constants below to VALUEX */
    if (count == VALUE1 || count == VALUE2 || count == VALUE3 || count == VALUE4)
        glDisable(GL_DEPTH_TEST);
    else
        glEnable(GL_DEPTH_TEST);
    glDrawElements_(mode, count, type, indices);
}

Interesting thought about multiplayer cheats and Wine

If anti-cheat tools would perform a sanity check of the OpenGL or DirectX DLL, they would only find the virtual DLL’s when a game is run in Wine, right? I’m wondering whether this sort of cheats can be made undetectable then. In a way I hope not, because cheaters are very annoying when you’re playing a game, but on the other hand, it would be an amazing technological achievement. Anyway, anti-cheat tools like PunkBuster don’t even work with Wine at the moment, so it might be a non-issue. What are your thoughts?

VN:F [1.6.3_896]
Rating: +4 (from 4 votes)
Categories: C, Linux, OpenGL, Programming

GBA programming in Linux

July 12th, 2007 Wesley 4 comments

GBA Rom

Mijn eerste GBA rom aan de linkerkant :) Nouja, afgekeken van een voorbeeldbestand…

Gisterenavond wou ik eens proberen om iets te programmeren voor mijn oude Game Boy Advance. Na wat rondgezocht te hebben bleek het niet eens zo moeilijk te zijn. Er is slechts weinig kennis nodig van ARM assembler. Programma’s kunnen gewoon in C/C++ worden geschreven en trage stukken nadien eventueel geoptimaliseerd met assembler.

Wel ga ik me moeten inwerken in het registersysteem van de Game Boy Advance.

Het was niet moeilijk om een cross compiler (compiler die uitvoerbare code genereert voor een ander platform dan hetgeen waarop de compiler draait) te compileren en gebruiken.

Mijn gecompileerd testproject werkte op emulators (zoals mednafen of visualboyadvance) maar het niet kon worden ingelezen door mijn EZF Advance client software! (software die ik gebruik om roms te uploaden naar een Flashkaart zodat ik de roms ook op mijn echte Game Boy Advance kan testen)
Screenshot van het probleem

Vandaag ben ik dus even bezig geweest met het uitzoeken van het probleem. De rom header moest gefixt worden en nog allerlei zaken. Ik had een perl script gevonden die alles voor me zou gefixt hebben, en de headers leken daarna inderdaad in orde, maar het programma wou nog steeds niet importeren in EZF Advance.

Toen vond ik devkitPro/devkitARM. Een heel pakket met alles wat ik nodig had. Heel veel GBA libs, voorbeelden, een cross compiler, header-fix-tool, etc.! Dus dat maar eens geïnstalleerd en een nieuw project gecompileerd op basis van één van de voorbeelden. En zie daar. Het draait nu ook op mijn Game Boy Advance (hardware)! Ik zou er een foto van hebben genomen, maar ik heb geen digitale camera :)

VN:F [1.6.3_896]
Rating: 0 (from 0 votes)
Categories: Assembler, C, C++, GBA, Hardware, Programming

XFiSH 0.99p: Blowfish encryptie voor XChat

May 6th, 2007 Wesley 4 comments

Ik ben gisteren beziggeweest met de XFiSH plugin voor XChat. Met deze plugin is het mogelijk om met Blowfish gecodeerde berichten te versturen en ontvangen in XChat.

Blowfish = strong cryptoEr waren echter een paar problemen met de originele XFiSH plugin. De source wou niet compileren en er was geen ondersteuning voor het Freenode netwerk. Een zekere Gnilor heeft de oorzaak van deze problemen gevonden.

Ook was het behoorlijk irritant dat je geen melding (notificatie) kreeg bij nieuwe berichten of hilights. Deze mogelijkheid heb ik dan maar meteen erbij geprogrammeerd, maar de notificaties werken momenteel enkel voor privéberichten op IRC.

Omdat ik XFiSH zelf alleen gebruik voor privéberichten had ik dus ook geen zin om het op kanalen te laten werken, maar het is niet zo moeilijk om het nu ook toe te passen bij kanalen… Misschien dat ik dat nog wel doe, als ik er zin in krijg. Ook moet de Freenode ondersteuning wat beter getest worden, maar voorlopig lijkt het erop alsof alles prima werkt.

Changelog 0.98 –> 0.99p

  • Ondersteuning voor het Freenode netwerk
  • Ondersteuning voor notificaties bij privéberichten (taskbar glow, icon blink, color usage in channel/user list)

Let op: dit is een onofficiële patch

Stap 1: compileerprobleem oplossen

1. Miracl downloaden, compileren en miracl.h kopiëren naar de source folder van XFiSH. In het archief van XFiSH zit standaard namelijk een te oude versie van miracl.

Stap 2: patch toepassen

Bekijk .diff file: http://pastebin.sk/en/1535/
Download .diff file: http://wesley.vidiqatch.org/files/xfish.diff

Ik heb de patch ook voorgecompileerd beschikbaar gemaakt op:
http://wesley.vidiqatch.org/files/xfish.so

VN:F [1.6.3_896]
Rating: -1 (from 1 vote)

Beryl code: Switcher tekst verbetering

November 1st, 2006 Wesley No comments

Tada :)

Verbeteringen aan het algoritme om de tekst te schalen in de Switcher.
Werkt nu zoals het hoort met praktisch elk lettertype/lettergrootte.

voor de patch:

Switcher

na de patch:

Switcher

Verbeteringen aan de code zijn van kracht in beryl-svn vanaf r898
edit: kleine update aan de vorige patch zit in r899 (hardgecodeerde nummers vervangen door betere, compactere code)

VN:F [1.6.3_896]
Rating: 0 (from 0 votes)

Beryl Code: Center/Pointer Split, Mystic Fire

October 30th, 2006 Wesley No comments

Center/Pointer Split

Ik heb voorlopig een patch voor mezelf gemaakt die het mogelijk maakt om in plaats van 1 globale “Zoom from Center” variabele 4 verschillende animations te hebben die we kunnen gebruiken voor verschillende acties/windowtypes.

De patch zal niet officieel worden geupload op SVN, omdat het slechts een tijdelijke patch is die uiteindelijk weer ongedaan moet gemaakt worden als het instellingensysteem van animations.c uitgebreid wordt. Tegen die tijd zal Magic Lamp 1 en 2 ook gewoon 1 globale Magic Lamp animatie worden met meer uitgebreide mogelijkheden per actie/windowtype.

Anyway, de voorlopige patch is hier te vinden: http://pastebin.mozilla.org/1097
Het is een .diff tegenover SVN revisie r877

Mystical Fire

Iemand op het Beryl forum had een patch geschreven om het vlammeneffect in animations.c willekleurige kleuren te geven, wat een leuk effect als gevolg had:

Mystic Fire

Het effect was jammer genoeg hardgecodeerd in de code door toxicgonzo, maar ik heb samengewerkt met toxicgonzo om dit effect een extra optie te maken in de bestaande programmacode en het is nu reeds in de officiële SVN verschenen als een extra optie in het configuratiescherm van Beryl sinds revisie r878

VN:F [1.6.3_896]
Rating: 0 (from 0 votes)

Smooth Cube Patch

October 15th, 2006 Wesley 1 comment

Ik heb een patch geschreven voor rotate.c (Rotate Cube plugin) om overal een vloeiende beweging van de draaiende kubus te krijgen.

Ik heb dit gefixt door timestep afhankelijk te maken van automatische (kubus ronddraaien met toetsenbord sneltoetsen) of manuele rotatie (kubus ronddraaien met muis)

Voor de patch was er 1 algemene timestep variabele, en dan had je maar 2 mogelijkheden:

  • timestep < 1
    • automatische rotatie: vloeiend, zonder terugkaatsing (bounce)
    • manuele rotatie: abrupte beëindiging van de beweging van de kubus zodra je de muis stil houdt
  • timestep > 1
    • automatische rotatie: ongewenst terugkaatsingseffect (bounce)
    • manuele rotatie: korte vloeiende glijbeweging van de kubus als je de muis stilhoudt

Met deze patch is het nu mogelijk om timestep < 1 te gebruiken voor automatische rotatie en timestep > 1 te gebruiken voor manuele rotatie. De waarden voor automatische en manuele timestep zijn natuurlijk gewoon aan te passen in beryl-settings-manager.

De patch tegenover svn r643:

Patch file (.diff) for rotate.c r643

Edit: Patch is niet meer nodig bij een nieuwe svn update!
De patch is geaccepteerd in svn r647

VN:F [1.6.3_896]
Rating: 0 (from 0 votes)