PDA

View Full Version : libcod on Arch Linux



Mitch
25th September 2013, 18:04
Hi, i am trying to get libcod (with mysql) working on Arch Linux.
I am using mariadb as mysql server.

If you have got 64bit Arch. Then download the mysql client files from there. (delete libmysqlclient.so and libmysqlclient.so.18 and copy libmysqlclient.so.18.0.0 2 times and rename them as the 2 files you removed)
https://www.archlinux.org/packages/extra/i686/libmariadbclient/

My startup line (no new lines otherwise the preloads are ignored)


LD_LIBRARY_PATH=/path/to/libs/:/path/to/libs/mysql LD_PRELOAD=/path/to/libs/libcod2_1_3.so ./cod2_lnxded +set dedicated "2" +exec server.cfg +map_rotate


But now after starting cod2 it crashes. I am using my own build from source. (also kung's build from 30 August crashes)

Error message from dmesg


[80191.481300] cod2_lnxded[6964]: segfault at 4 ip 00000000f770a37b sp 00000000ffae0820 error 4 in libcod2_1_3.so[f7702000+12000]

kung foo man
25th September 2013, 23:48
since the instruction pointer (ip) is only valid in your .so, you need to upload it :)

Mitch
26th September 2013, 10:39
since the instruction pointer (ip) is only valid in your .so, you need to upload it :)

I had to rebuild it, because i deleted it again when i was testing your build.

kung foo man
26th September 2013, 11:12
By the IP, it might be gsc_utils_ClientCommand() which is crashing, can you test it without this callback?

Can you specify where it is crashing? Is libcod able to print some messages before crash or can't it start at all?

Mitch
26th September 2013, 13:11
By the IP, it might be gsc_utils_ClientCommand() which is crashing, can you test it without this callback?

Can you specify where it is crashing? Is libcod able to print some messages before crash or can't it start at all?

When i comment my persistence gsc out of my callbacksetup then it doesn't give me a segmentation fault. But when i add:



std\io::print("TEST");


Then it crashes again.

kung foo man
26th September 2013, 18:15
Can you try to add many normal printf's to this function in https://github.com/kungfooman/libcod/blob/master/gsc.cpp ?




int cdecl_injected_closer()
{
int function;
int playerid;


printf by printf you will get nearer to the buggy function.

Mitch
26th September 2013, 22:05
Can you try to add many normal printf's to this function in https://github.com/kungfooman/libcod/blob/master/gsc.cpp ?




int cdecl_injected_closer()
{
int function;
int playerid;


printf by printf you will get nearer to the buggy function.

It crashes here:


printf("scriptengine> test b3\n");


if (!stackGetParamInt(0, &function))
{
printf("scriptengine> ERROR: closer(): param \"function\"[0] has to be an integer!\n");
return 0;
}

printf("scriptengine> test b4\n");


It only shows 'scriptengine> test b3' and not the other 2 messages. (commenting the printf ...ERROR: closer().. out doesn't show the 'test b4' message.)

kung foo man
26th September 2013, 22:14
The function is in https://github.com/kungfooman/libcod/blob/master/gsc.cpp



// todo: check if the parameter really exists (number_of_params)
int stackGetParamInt(int param, int *value)
{
//printf("stackGetParamInt() start...");
aStackElement *scriptStack = *(aStackElement**)getStack();
aStackElement *arg = scriptStack - param;
if (arg->type != STACK_INT)
return 0;
*value = (int)arg->offsetData;
//printf("... end\n");
return 1;
}


Now check in detail where it is crashing :)

Mitch
26th September 2013, 22:23
The function is in https://github.com/kungfooman/libcod/blob/master/gsc.cpp



// todo: check if the parameter really exists (number_of_params)
int stackGetParamInt(int param, int *value)
{
//printf("stackGetParamInt() start...");
aStackElement *scriptStack = *(aStackElement**)getStack();
aStackElement *arg = scriptStack - param;
if (arg->type != STACK_INT)
return 0;
*value = (int)arg->offsetData;
//printf("... end\n");
return 1;
}


Now check in detail where it is crashing :)



int stackGetParamInt(int param, int *value)
{
//printf("stackGetParamInt() start...");
printf("scriptengine> test c1\n");
aStackElement *scriptStack = *(aStackElement**)getStack();
printf("scriptengine> test c2\n");
aStackElement *arg = scriptStack - param;
printf("scriptengine> test c3\n");
if (arg->type != STACK_INT)
return 0;
printf("scriptengine> test c4\n");
*value = (int)arg->offsetData;
printf("scriptengine> test c5\n");
//printf("... end\n");
return 1;
}


It prints c1, c2 and c3.

kung foo man
26th September 2013, 22:28
It can be either the dereferencing of value for writing (would be very strange) or the dereferencing of arg for reading.

Try:




printf("scriptengine> test c4 value=%.8x scriptStack=%.8x arg=%.8x\n", value, scriptStack, arg);

Mitch
26th September 2013, 22:32
It can be either the dereferencing of value for writing (would be very strange) or the dereferencing of arg for reading.

Try:




printf("scriptengine> test c4 value=%.8x scriptStack=%.8x arg=%.8x\n", value, scriptStack, arg);


scriptengine> test c4 value=ff805778 scriptStack=00000000 arg=00000000

kung foo man
27th September 2013, 17:29
For some reason the stack pointer isn't pointing to the stack on Arch linux. I have no idea how that should happen. Some ideas:

- are you messing with some other functions before this happens?
- which compiler do you use?
- are there maybe some security "features" in Arch linux which denies read/write/execute rights for LD_PRELOAD

Mitch
30th September 2013, 08:42
[09:37] kung foo man: #if COD_VERSION == COD4_1_7

//08048000-0817d000 rwxp 00000000 00:8e 8716292 /root/helper/game_cod4/cod4_1_7-bin
//0817d000-0826a000 r-xp 00135000 00:8e 8716292 /root/helper/game_cod4/cod4_1_7-bin
//0826a000-08274000 rw-p 00221000 00:8e 8716292 /root/helper/game_cod4/cod4_1_7-bin

mprotect((void *)0x08048000, 0x135000, PROT_READ | PROT_WRITE | PROT_EXEC);
mprotect((void *)0x0817d000, 0xED000, PROT_READ | PROT_WRITE | PROT_EXEC);
mprotect((void *)0x0826a000, 0xA000, PROT_READ | PROT_WRITE | PROT_EXEC);
#else

// allow to write in executable memory
mprotect((void *)0x08048000, 0x135000, PROT_READ | PROT_WRITE | PROT_EXEC);
#endif
[09:37] kung foo man: in https://github.com/kungfooman/libcod/blob/master/libcod.cpp
[09:37] kung foo man: maybe those addresses changed
[09:37] kung foo man: cat /proc/$cod2pid/maps

[mitch@Gazpacho cod2]$ cat /proc/1739/maps
08048000-0817d000 r-xp 00000000 fe:00 110100910 /mnt/cobra/Spellen/cod2/cod2_lnxded
0817d000-08189000 rw-p 00134000 fe:00 110100910 /mnt/cobra/Spellen/cod2/cod2_lnxded
08189000-08a70000 rw-p 00000000 00:00 0
0a8c7000-0ad53000 rw-p 00000000 00:00 0 [heap]
e5560000-e5631000 r-xp 00000000 fe:00 111019504 /mnt/cobra/Spellen/cod2/pb/pbcls.so
e5631000-e5640000 rw-p 000d0000 fe:00 111019504 /mnt/cobra/Spellen/cod2/pb/pbcls.so
e5640000-e57ad000 rw-p 00000000 00:00 0
e57ad000-e58f5000 r-xp 00000000 fe:00 111019510 /mnt/cobra/Spellen/cod2/pb/pbsv.so
e58f5000-e5902000 rw-p 00147000 fe:00 111019510 /mnt/cobra/Spellen/cod2/pb/pbsv.so
e5902000-ed124000 rw-p 00000000 00:00 0
ed124000-ed137000 r-xp 00000000 00:0f 147677 /usr/lib32/libresolv-2.18.so
ed137000-ed138000 ---p 00013000 00:0f 147677 /usr/lib32/libresolv-2.18.so
ed138000-ed139000 r--p 00013000 00:0f 147677 /usr/lib32/libresolv-2.18.so
ed139000-ed13a000 rw-p 00014000 00:0f 147677 /usr/lib32/libresolv-2.18.so
ed13a000-ed13c000 rw-p 00000000 00:00 0
ed13c000-ed141000 r-xp 00000000 00:0f 147669 /usr/lib32/libnss_dns-2.18.so
ed141000-ed142000 r--p 00004000 00:0f 147669 /usr/lib32/libnss_dns-2.18.so
ed142000-ed143000 rw-p 00005000 00:0f 147669 /usr/lib32/libnss_dns-2.18.so
ed143000-ed14e000 r-xp 00000000 00:0f 147670 /usr/lib32/libnss_files-2.18.so
ed14e000-ed14f000 r--p 0000a000 00:0f 147670 /usr/lib32/libnss_files-2.18.so
ed14f000-ed150000 rw-p 0000b000 00:0f 147670 /usr/lib32/libnss_files-2.18.so
ed15f000-ed165000 r-xp 00000000 fe:00 111019498 /mnt/cobra/Spellen/cod2/pb/pbags.so
ed165000-ed168000 rw-p 00005000 fe:00 111019498 /mnt/cobra/Spellen/cod2/pb/pbags.so
ed168000-f716d000 rw-p 00000000 00:00 0
f716f000-f7408000 rw-p 00000000 00:00 0
f7408000-f75b1000 r-xp 00000000 00:0f 147622 /usr/lib32/libc-2.18.so
f75b1000-f75b3000 r--p 001a9000 00:0f 147622 /usr/lib32/libc-2.18.so
f75b3000-f75b4000 rw-p 001ab000 00:0f 147622 /usr/lib32/libc-2.18.so
f75b4000-f75b7000 rw-p 00000000 00:00 0
f75b7000-f75d0000 r-xp 00000000 00:0f 147970 /usr/lib32/libgcc_s.so.1
f75d0000-f75d1000 rw-p 00018000 00:0f 147970 /usr/lib32/libgcc_s.so.1
f75d1000-f75d2000 rw-p 00000000 00:00 0
f75d2000-f7616000 r-xp 00000000 00:0f 147675 /usr/lib32/libm-2.18.so
f7616000-f7617000 r--p 00043000 00:0f 147675 /usr/lib32/libm-2.18.so
f7617000-f7618000 rw-p 00044000 00:0f 147675 /usr/lib32/libm-2.18.so
f7618000-f76c8000 r-xp 00000000 00:0f 135561 /usr/lib32/libstdc++.so.5.0.7
f76c8000-f76cd000 rw-p 000b0000 00:0f 135561 /usr/lib32/libstdc++.so.5.0.7
f76cd000-f76d2000 rw-p 00000000 00:00 0
f76d2000-f76ea000 r-xp 00000000 00:0f 147604 /usr/lib32/libpthread-2.18.so
f76ea000-f76eb000 r--p 00017000 00:0f 147604 /usr/lib32/libpthread-2.18.so
f76eb000-f76ec000 rw-p 00018000 00:0f 147604 /usr/lib32/libpthread-2.18.so
f76ec000-f76ee000 rw-p 00000000 00:00 0
f76ee000-f76f1000 r-xp 00000000 00:0f 147674 /usr/lib32/libdl-2.18.so
f76f1000-f76f2000 r--p 00002000 00:0f 147674 /usr/lib32/libdl-2.18.so
f76f2000-f76f3000 rw-p 00003000 00:0f 147674 /usr/lib32/libdl-2.18.so
f76f3000-f7710000 rw-p 00000000 00:00 0
f7710000-f7711000 r-xp 00000000 00:00 0 [vdso]
f7711000-f7731000 r-xp 00000000 00:0f 147621 /usr/lib32/ld-2.18.so
f7731000-f7732000 r--p 0001f000 00:0f 147621 /usr/lib32/ld-2.18.so
f7732000-f7733000 rw-p 00020000 00:0f 147621 /usr/lib32/ld-2.18.so
ffb8d000-ffbad000 rwxp 00000000 00:00 0 [stack]
ffbad000-ffbae000 rw-p 00000000 00:00 0

kung foo man
30th September 2013, 08:48
08048000-0817d000 r-xp 00000000 fe:00 110100910 /mnt/cobra/Spellen/cod2/cod2_lnxded
0817d000-08189000 rw-p 00134000 fe:00 110100910 /mnt/cobra/Spellen/cod2/cod2_lnxded


The first two lines represent the memory of cod2, the 1nd is already in libcod:

https://github.com/kungfooman/libcod/blob/master/libcod.cpp



mprotect((void *)0x08048000, 0x135000, PROT_READ | PROT_WRITE | PROT_EXEC);


0x135000 is calculated by 0817d000 - 08048000.

Try to add this mprotect:


mprotect((void *)0x08048000, 0x135000, PROT_READ | PROT_WRITE | PROT_EXEC);
mprotect((void *)0x0817d000, 0xC000, PROT_READ | PROT_WRITE | PROT_EXEC);

Mitch
13th October 2013, 11:42
It is solved now in the latest commit (1.0 support), but you need to edit doit.sh. Because now COD2_VERSION is renamed to COD_VERSION and in the doit.sh this isn't set right yet for 1.3.

kung foo man
13th October 2013, 12:07
Nice that it works now, oals fixed the wrong define now on git.

voron00
25th December 2018, 14:55
Just a heads up to anyone running cod2 server on arch linux, they just removed lib32-libstdc++5 from official packages and the one in AUR doesn't even build so just get prebuilt one from archlinux32 repo https://packages.archlinux32.org/extra/i686/libstdc++5/ you can just place it in cod2 folder or move it to your lib32.

kung foo man
25th December 2018, 17:44
Could you please upload the `libstdc++.so` file, Voron? I tried to download from that site but "404 Not Found"

I still have ForeignLinux installed on Windows10 (which is Arch basically), but the `libstdc++.so`from Debian doesn't work, so I would like to test the native file.

voron00
25th December 2018, 17:51
Could you please upload the `libstdc++.so` file, Voron? I tried to download from that site but "404 Not Found"

I still have ForeignLinux installed on Windows10 (which is Arch basically), but the `libstdc++.so`from Debian doesn't work, so I would like to test the native file.

1575

kung foo man
25th December 2018, 21:15
Thank you alot and fuck my life, IT WORKS

Not tested with full server and libcod yet, but this looks very good:

1576

Arch + ForeignLinux manages what WSL can't, LOL

I'm a bit of an Arch potato, so gonna slowly figure some stuff out... installing gcc etc.



[root@ForeignLinux ~]# LD_LIBRARY_PATH=. ./cod2_lnxded_1_2


GitHub repo: https://github.com/wishstudio/flinux

Direct download of arch linux with .exe etc. for starting /bin/bash: https://xysun.me/static/flinux-archlinux.7z

IzNoGoD
27th December 2018, 10:35
The .cfg file is read from an iwd. Are you sure its reading iwds?

kung foo man
27th December 2018, 22:12
Yea, I tested without files, with files it fails on missing UDP support: https://killtube.org/showthread.php?3146-libcod-on-ForeignLinux-arch

But I can't extend ForeignLinux with my current OS/software setup, my flinux build just crashes