Originally Posted by
Czepek
Check *DEAD* project on google code:
Click!
EDIT:
Ooops... Didn't saw that this thread was made one year a go
Regards, Czepek!
Way to revive a really old thread
. Zionz is actually the only person who has done it, I used a different method. Zionz method uses pthreads and is actually pretty complex. Basically
1)Attach to process
2)Get copy of tibias registers so it can be restored
3)Read a block of tibias code segment so it can be restored
4)Overwrite said block with code to call send. Code ends in software breakpoint
5)Modify instruction pointer to point to injected code and set registers
6)Tibia code hits breakpoint, restore all damage done to the client
7)Detach
Not quite attach remote thread
, although something similar is possible using the above technique. However linux has several other methods of screwing with other peoples processes. I would have personally used LD_PRELOAD.
The attached file prints out the current xtea key over and over again by hooking into tibia's sigarlm signal. The code runs inside tibias address space, so you can do anything you like. To use it
hachiko:~/Tibia gcc -m32 -shared -o sigaction.so sigaction.c -Wall -fPIC
hachiko:~/Tibia LD_PRELOAD=./sigaction.so ./Tibia
Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <dlfcn.h>
#include <unistd.h>
#include <signal.h>
/* Tibia uses timers for all its animations. This is a relatively nice entry
* point for our code because it will be called about 10 times per second. If
* you only require your code to be run on read/write calls (x-input and
* networking), then you could just as easily hook read and write.
*/
int (*old_sigaction)(int signum, const struct sigaction *act,
struct sigaction *oldact) = NULL;
static void new_handler(int arg);
void (*old_handler)(int arg) = NULL;
/* Resolve a symbol from a library. If this fails, exit with an error message.
* Do not bother trying to recover has there is little we can do
*/
void *safe_dlsym(const char *path, const char *sym)
{
void *ret_sym;
void *hdl = dlopen(path, RTLD_NOW);
if (! hdl) {
fprintf(stderr, "could not open %s: %s\n", path, dlerror());
exit(1);
}
if (! (ret_sym = dlsym(hdl, sym))) {
fprintf(stderr, "could resolve %s: %s\n", sym, dlerror());
exit(1);
}
dlclose(hdl);
return ret_sym;
}
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact)
{
old_sigaction = safe_dlsym("libc.so.6", "sigaction");
if (signum == SIGALRM) {
int error;
struct sigaction new_act = *act;
new_act.sa_handler = new_handler;
fprintf(stdout, "sigalrm hooked\n");
error = old_sigaction(signum, &new_act, oldact);
/* Patch the oldact to make it appear legit to tibia */
if (oldact && old_handler) {
oldact->sa_handler = new_handler;
}
/* Store the old handler so we can use it later */
old_handler = act->sa_handler;
return error;
} else {
return old_sigaction(signum, act, oldact);
}
}
#define XTEA_ADDRESS 0x085b2230
void new_handler(int arg)
{
/* Call tibias handler, doesn't really matter where you put this */
old_handler(arg);
/* Do something useful. You are in the clients memory space */
printf("The current XTEA key is %x %x %x %x\n",
*(int32_t *)(XTEA_ADDRESS + 0),
*(int32_t *)(XTEA_ADDRESS + 4),
*(int32_t *)(XTEA_ADDRESS + 8),
*(int32_t *)(XTEA_ADDRESS + 12));
}