lkubuntu

A listing of random software, tips, tweaks, hacks, and tutorials I made for Ubuntu

Category Archives: terminal

Injecting code into running process with linux-inject

I was about to title this “Injecting code, for fun and profit”, until I realized that this may give a different sense than I originally intended… :P

I won’t cover the reasons behind doing such, because I’m pretty sure that if you landed on this article, you would already have a pretty good sense of why you want to do this …. for fun, profit, or both ;)

Anyway, after trying various programs and reading on how to do it manually (not easy!), I came across linux-inject, a program that injects a .so into a running application, similar to how LD_PRELOAD works, except that it can be done while a program is running… and it also doesn’t actually replace any functions either (but see the P.S. at the bottom of this post for a way to do that). In other words, maybe ignore the LD_PRELOAD simile :P

The documentation of it (and a few other programs I tried) was pretty lacking though. And for good reason, the developers probably expect that most users who would be using these kinds of programs wouldn’t be newbies in this field, and would know exactly what to do. Sadly, however, I am not part of this target audience :P It took me a rather long time to figure out what to do, so in hopes that it may help someone else, I’m writing this post! :D

Let’s start by quickly cloning and building it:

git clone https://github.com/gaffe23/linux-inject.git
cd linux-inject
make

Once that’s done, let’s try the sample example bundled in with the program. Open another terminal (so that you have two free ones), cd to the directory you cloned linux-inject to (e.g. cd ~/workspace/linux-inject), and run ./sample-target.

Back in the first terminal, run sudo ./inject -n sample-target sample-library.so

What this does is that it injects the library sample-library.so to a process by the -name of sample-target. If instead, you want to choose your victim target by their PID, simply use the -p option instead of -n.

But … this might or might not work. Since Linux 3.4, there’s a security module named Yama that can disable ptrace-based code injections (or code injections period, I doubt there is any other way). To allow this to work, you’ll have to run either one of these commands (I prefer the second, for security reasons):

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope # Allows any process to inject code into any other process started by the same user. Root can access all processes
echo 2 | sudo tee /proc/sys/kernel/yama/ptrace_scope # Only allows root to inject code

Try it again, and you will hopefully see “I just got loaded” in-between the “sleeping…” messages.

Before I get to the part about writing your own code to inject, I have to warn you: Some applications (such as VLC) will segfault if you inject code into them (via linux-inject, I don’t know about other programs, this is the first injection program that I managed to get working, period :P). Make sure that you are okay with the possibility of the program crashing when you inject the code.

With that (possibly ominous) warning out of the way, let’s get to writing some code!

#include <stdio.h>

__attribute__((constructor))
void hello() {
    puts("Hello world!");
}

If you know C, most of this should be pretty easy to understand. The part that confused me was __attribute__((constructor)). All this does is that it says to run this function as soon as the library is loaded. In other words, this is the function that will be run when the code is injected. As you may imagine, the name of the function (in this case, hello) can be whatever you wish.

Compiling is pretty straightforward, nothing out of the ordinary required:

gcc -shared -fPIC -o libhello.so hello.c

Assuming that sample-target is running, let’s try it!

sudo ./inject -n sample-target libhello.so

Amongst the wall of “sleeping…”, you should see “Hello world!” pop up!

There’s a problem with this though: the code interrupts the program flow. If you try looping puts("Hello world!");, it will continually print “Hello world!” (as expected), but the main program will not resume until the injected library has finished running. In other words, you will not see “sleeping…” pop up.

The answer is to run it in a separate thread! So if you change the code to this …

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void* thread(void* a) {
    while (1) {
        puts("Hello world!");
        usleep(1000000);
    }
    return NULL;
}

__attribute__((constructor))
void hello() {
    pthread_t t;
    pthread_create(&t, NULL, thread, NULL);
}

… it should work, right? Not if you inject it to sample-target. sample-target is not linked to libpthread, and therefore, any function that uses pthread functions will simply not work. Of course, if you link it to libpthread (by adding -lpthread to the linking arguments), it will work fine.

However, let’s keep it as-is, and instead, use a function that linux-inject depends on: __libc_dlopen_mode(). Why not dlopen()? dlopen() requires the program to be linked to libdl, while __libc_dlopen_mode() is included in the standard C library! (glibc’s version of it, anyways)

Here’s the code:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <dlfcn.h>

/* Forward declare these functions */
void* __libc_dlopen_mode(const char*, int);
void* __libc_dlsym(void*, const char*);
int   __libc_dlclose(void*);

void* thread(void* a) {
    while (1) {
        puts("Hello world!");
        usleep(1000000);
    }
}

__attribute__((constructor))
void hello() {
    /* Note libpthread.so.0. For some reason,
       using the symbolic link (libpthread.so) will not work */
    void* pthread_lib = __libc_dlopen_mode("libpthread.so.0", RTLD_LAZY);
    int(*pthread_lib_create)(void*,void*,void*(*)(void*),void*);
    pthread_t t;

    *(void**)(&pthread_lib_create) = __libc_dlsym(pthread_lib, "pthread_create");
    pthread_lib_create(&t, NULL, thread, NULL);

    __libc_dlclose(pthread_lib);
}

If you haven’t used the dl* functions before, this code probably looks absolutely crazy. I would try to explain it, but the man pages are quite readable, and do a way better job of explaining than I could ever hope to try.

And on that note, you should (hopefully) be well off to injecting your own code into other processes!

If anything doesn’t make sense, or you need help, or just even to give a thank you (they are really appreciated!!), feel more than free to leave a comment or send me an email! :D And if you enjoy using linux-inject, make sure to thank the author of it as well!!

P.S. What if you want to change a function inside the host process? This tutorial was getting a little long, so instead, I’ll leave you with this: http://www.ars-informatica.com/Root/Code/2010_04_18/LinuxPTrace.aspx and specifically http://www.ars-informatica.com/Root/Code/2010_04_18/Examples/linkerex.c . I’ll try to make a tutorial on this later if someone wants :)

Advertisements

Openlux 0.2 beta – Animations, iOS port

I wrote openlux around 2 and a half weeks ago, as a simple, libre alternative to f.lux that addresses a few issues I’ve encountered with it. I’ve since used it everyday, and I’ve actually noticed an improvement in my sleep!

However, my iPad still uses f.lux (or, until today, at least). No, in this case, I’m not worried about the fact that f.lux is proprietary (it’s an iPad), but earlier, when my sleep was really messed up (and by messed up, I mean, I was going to sleep at 7-8am), f.lux would automatically switch to 3400K (instead of 2300K), which definitely didn’t have a positive impact on my sleep. Also, it only goes down to 2300K, doesn’t allow much customizability, and doesn’t always work how I want it to work, etc.

So after spending quite a long time (basically ever since I released the first version of openlux) working on the port, it finally works!!! It doesn’t work as well as I wanted it to (multiple colors output the same value, compressing the color range … I tried lerping values, but it ended up giving garbage), but at least it works!

Animations literally took about the last hour of developing this version (in other words, barely any time at all, compared to the time needed to develop the iOS port), since, luckily, I only encountered one bug while making it. The point of animations is not for visual bling, but rather to make it easier on the eyes if it’s run automatically (e.g. via cron).

Other than those, there are a few minor features, such as optional relative adjustment of colors (“-b 10” will set the blue channel to 10, “-b +10” will add 10 to the blue channel, and “-b -10” will remove 10), and saving/resetting gamma values (mainly just a by-product of working on the iOS port).

If anyone would be interested in testing this on their iDevices, I would really appreciate it ^^ Though it works fine on my 1st generation iPad, I don’t know if it will work on other devices too. I wrote instructions on how to compile and run it here: https://github.com/AnonymousMeerkat/openlux/wiki/Compiling-for-iOS :) I’m not aware of this being able to cause any permanent damage to your device (my device works fine now, even after the display being severely messed up multiple times), but if you’re scared, stick with f.lux for now. Quick note: it doesn’t work on iOS <4, since it needs to retrieve the gamma table (which iOS versions <4 don’t support).

To wrap up, here’s a few examples of the new features that come with openlux 0.2:

openlux -k 1000 -a 10000         # Animates to 1000K in 10 seconds (10000 milliseconds)
openlux -k 1000 -a 100000 -d 100 # Animates to 1000K in 100 seconds, with a delay of 100 milliseconds per "frame" (less CPU usage)
openlux -k 1000 -g +10           # Sets the color temperature to 1000K, but adds 10 to the green channel
openlux -R                       # Resets to the last saved gamma table (openlux automatically saves the gamma table the first time it's run per boot)
openlux -s                       # Saves the gamma table

How to set up WineASIO

Step 1: Install WineASIO

If you use ubuntu, run this in a terminal:

sudo apt-get install software-properties-common wget
sudo add-apt-repository ppa:kxstudio-debian/kxstudio
sudo apt-get update
sudo apt-get install kxstudio-repos
sudo apt-get update
sudo apt-get install wineasio

If you use Arch Linux:

Add the Arch Audio repository, then run in a terminal:

sudo pacman -Sy wineasio

Step 2: Register WineASIO

If you have a 32-bit WINE prefix, or you have a 64-bit one, and you want to run a 32-bit ASIO application (e.g. a DAW), run this:

regsvr32 wineasio

If you have a 64-bit WINE prefix, and you want to run a 64-bit ASIO application:

wine64 regsvr32 wineasio

If everything went smoothly, you should see a message similar to:

Successfully registered DLL wineasio.dll

However, you may receive:

Failed to load DLL wineasio.dll

In my case, the reason why this message occurred, is that wineasio.dll was installed to the wrong location. I had 2 problems, actually. It was first installed to /usr/lib/wine, not /usr/local/lib/wine (I have a custom-built version of WINE), and second, even if it had been installed to /usr/local/lib/wine, it wouldn’t have worked, because, in my case, WINE loaded 64-bit libraries only from /usr/local/lib64/wine, and 32-bit libraries only from /usr/local/lib/wine. The package had installed the 32-bit version of wineasio to /usr/lib32/wine, and the 64-bit version to /usr/lib/wine.

Try moving the wineasio .so’s to these places:

  • 64-bit wineasio .so: /usr/lib64/wine
  • 32-bit wineasio .so: /usr/lib/wine

Then try again. If you still have problems, leave a comment below, and I’ll try my best to help =)

Step 3: Setup JACK

WineASIO uses JACK as the backend for the audio, so, not surprisingly, JACK has to be setup correctly for WineASIO to function correctly. I wrote an article a while back about how to do this.

Step 4: Profit!

It’s that simple! Now all you have to do is to load up the application you want, and set the ASIO driver to WineASIO =)

Relinux – An easy way to create a Linux distro

Note: I know this post is a mess, I’m sorry. I’ll try to fix it sometime soon

Note #2: Relinux is now dead: https://lkubuntu.wordpress.com/2014/09/14/im-quitting-relinux/

Remastersys has been around for a long time, and though it hasn’t been updated in a long time (EDIT: It was dead, but now he is maintaining it), many people still use it. Remastersys is very closed in what you can do with it (for example, it’s hard to change the splash image), and sometimes you have to edit the code just to be able to change more options that what is given in the remastersys.conf file.

I created 2 systems with it (one personal and one public), and I didn’t like the lack of options, so I decided to make my own script based on it, to give much more customization. Though it is still at a beta stage, it gives many more options, and much more usability.

The goal for relinux is to let someone make his own Linux distro easily, while the goal for remastersys is to make personal distros and backups.

To install, download the latest tar.gz file at https://launchpad.net/relinux. Untar it, and follow the instructions in the INSTALL file.

You can customize the system as much as you would like, except for these limitations (most of which will be removed in a future release):

  • It only supports GRUB2, so no BURG or GRUB-Legacy
  • It must have an X11 display, since Ubiquity (the installer) requires X11 to run
  • You cannot use another installer than Ubiquity
  • The compressed filesystem size must be below 4GB (no workaround). It will tell you if it’s over 4GB (compressed), but I recommend that you keep your system size below 6GB (uncompressed).
  • It will install metacity, but in 0.3, this is removed.
After you have customized your system at your liking, you will need to create a configuration file. To do this, simply type in a Terminal window:
cp /etc/relinux/relinux.conf ./relinux.conf
sed -i 's:EXCLUDES="\(.*\)":EXCLUDES="\1 '`readlink -f ./relinux.conf`'":g' ./relinux.conf
readlink -f ./relinux.conf

The last command will tell you where the configuration file is located. Edit that file to your liking. Some splash screens are located in /etc/relinux/relinux/splash.
Before you start editing, if you want to save your settings/themes, do this (replace USERNAME by your actual username):
  1. Press CTRL+ALT+F3
  2. Log in as your normal user
  3. Type: sudo passwd
  4. Enter a password for root
  5. Type: exit
  6. Log in as root (with the password you gave for root)
  7. Type: usermod -d /etc/skel USERNAME; chown -R USERNAME /etc/skel
  8. Reboot your system (can be done with the reboot command)
Then you can log into your normal user, and all of your changes to the theme, desktop background, panel configuration etc… will be saved.
Once you have finished editing it, you will want to create the ISO file, so type this into the Terminal window:
sudo relinux fullclean ./relinux.conf
sudo relinux iso ./relinux.conf
The last (and final) step will take a while.
Simply follow the directions (if there are any).

I decided to make a comparison chart with Relinux and Remastersys:

Relinux Remastersys
Actively Developed T T
DIST/ISO mode T T
Backup mode T (will be removed in 0.4, as remastersys is good for the backup mode, relinux is not) T
Splash Image Customization T F
Can use T T
GUI F (will add in 0.4) T
WUBI T F
Language BASH (will be Python in 0.4) BASH
If you have any questions/comments, feel free to leave a comment on here!

How to fix rfkill Issues

I recently tried making wireless work on a laptop, but I got problems with rfkill showing that it was hard blocked. In fact, the wireless switch was off, but when I set it on, it still showed that it was hard blocked.

Here is a solution that I found that works:

  1. Make sure that your wireless switch is on
  2. Type in a Terminal window:
    sudo rfkill unblock all
    for x in `for i in \`lspci -nn | grep 02[80] | awk '{print $1}' | tr ' ' '\n'\`; do lspci -vvvs $i; done | grep "Kernel driver in use:" | awk '{print $NF}'`; do sudo rmmod $x; sudo modprobe $x; done
    sudo sed -i 's:false:true:g' /var/lib/NetworkManager/NetworkManager.state
    sudo rfkill unblock all
    sudo rm /dev/rfkill
  3. Reboot

If you still can’t connect after the reboot, type this into a Terminal window:
sudo rfkill unblock all
for x in `for i in \`lspci -nn | grep 02[80] | awk '{print $1}' | tr ' ' '\n'\`; do lspci -vvvs $i; done | grep "Kernel driver in use:" | awk '{print $NF}'`; do sudo rmmod $x; sudo modprobe $x; done
sudo rfkill unblock all

If you had any problems with this post, feel free to leave a comment!

Make XFCE4 Bottom Dock look like Docky/AWN

I recently installed XFCE 4.8, and I was happy with it, except that I didn’t like that the top panel had the window list, and the bottom dock was just a launcher.

I decided to move the window list at the top to the bottom panel, and remove the launchers.

Screenshot: http://img24.imageshack.us/img24/4427/panel20screenshot.png

To change your panel configuration to the one that the screenshot shows:

  1. Type this into a Terminal window
    xfce4-panel -q
    killall -KILL xfconfd
    killall -KILL xfsettingsd
    cd ~/.config/xfce4/xfconf/xfce-perchannel-xml/
    mv xfce4-panel.xml xfce4-panel.xml.bak
    wget http://dl.dropbox.com/u/21016209/xfce4-panel.xml
  2. Log out and log back in (killall -KILL xfce4-session)

If you have any problems, feel free to comment below.

Sound Troubleshooting

This tutorial will try to help you hear sound again! Notice that there is a newer version of this guide available here: https://docs.google.com/document/d/1iTlJ8BfqXUjaHO__TEdlkvuqB1WLOkGaudngc5SFLMI/edit

If you don’t hear sound in flash, open up a Terminal window, and type in it:
sudo ln -s /usr/lib/libesd.so.0 /usr/lib/libesd.so.1
sudo mkdir -p /tmp/.esd/
sudo touch /tmp/.esd/socket

Preliminary Checks:

Make sure your speakers are on turned on, not muted, and on full volume
Make sure your speakers are plugged in correctly (usually plugged into a green jack)

Check 1: Check if the problem is the hardware or the software

Burn a LiveCD of any system (preferrably ubuntu), put it in your disk tray, and reboot. See if you can hear sound (by playing an audio file, or something). If you have windows, see if sound works there.
Success: You hear sound, go to Check 2
Failure: You do not hear sound.
This can be caused by 4 things:

  1. The LiveCD does not support sound correctly.
  2. Your BIOS disabled your soundcard. Reboot, and hit the key to enter your BIOS (usually Esc, Delete, F1, F2, F8, or F12). *TODO: Add more info*
  3. Your soundcard is broken. Replace it
  4. Your speakers are broken. Replace them

Check 2: Check if ALSA recognizes your soundcard(s)

Boot back into your normal system, open up a Terminal window, and type in it:

aplay -l

Success: You see your soundcard(s)
Type in the Terminal window:

sudo usermod -aG audio `whoami`

Log out, and log back in, then follow the alsamixer section, making sure everything is at full volume, and then test your sound using (you might have to run it a few times):

aplay /usr/share/sounds/alsa/Front_Center.wav

Success: You hear sound
Failure: You do not hear sound. Use this guide: http://idyllictux.wordpress.com/2009/04/21/ubuntu-904-jaunty-keeping-the-beast-pulseaudio-at-bay/

Reboot and then follow the alsamixer section

Failure 1: You see something similar to:

**** List of PLAYBACK Hardware Devices ****
ALSA lib conf.c:3643:(snd_config_update_r) Cannot access file /usr/share/alsa/alsa.conf
ALSA lib control.c:882:(snd_ctl_open_noupdate) Invalid CTL hw:0
aplay: device_list:249: control open (0): No such file or directory
ALSA lib conf.c:3643:(snd_config_update_r) Cannot access file /usr/share/alsa/alsa.conf
ALSA lib control.c:882:(snd_ctl_open_noupdate) Invalid CTL hw:1
aplay: device_list:249: control open (1): No such file or directory
ALSA lib conf.c:3643:(snd_config_update_r) Cannot access file /usr/share/alsa/alsa.conf
ALSA lib control.c:882:(snd_ctl_open_noupdate) Invalid CTL hw:2
aplay: device_list:249: control open (2): No such file or directory

Simply type in it:

sudo apt-get install --reinstall libasound2

Then follow the Alsamixer section
Failure 2: You see something similar to:

aplay: device_list:221: no soundcard found...

Type in the Terminal window:

sudo aplay -l

Success: You see your soundcard(s).
Type in the Terminal window:
sudo usermod -aG audio `whoami`
Reboot, and follow Check 2
Failure 2: Follow Check 3

Check 3: Check if your system recognizes your soundcard(s)

Type in the Terminal window:

lspci -nn | grep '04[80][13]'

Success: You see results, move on to Check 4
Failure: You do not see results, which means that Ubuntu does not detect your soundcard. *TODO: Add more info*

Check 4: Check if your soundcard(s) are supported by ALSA

Look for your soundcard here: http://www.alsa-project.org/main/index.php/Matrix:Main
Success: Your soundcard is listed. Move on to Check 6
Failure: Your soundcard isn’t listed. Move on to Check 5

Check 5: Check if your soundcard(s) are supported by OSS 4
NOTICE: This technique is listed in https://help.ubuntu.com/community/SoundTroubleshooting as a last resort. Use this technique with caution because it removes ALSA, the default sound system in Ubuntu. Do not be surprised if you sometimes randomly log out.

Look for your soundcard here: http://opensound.hg.sourceforge.net/hgweb/opensound/opensound/file/3db750724c2d/devlists/Linux
Success: Your soundcard is listed. Follow the instructions here: https://help.ubuntu.com/community/OpenSound, and then here: http://ubuntuforums.org/showpost.php?p=9872284&postcount=4
Failure: *TODO: Add more info*

Check 6: Check if your the driver for your soundcard(s) is installed

Type in the terminal window:

sudo modprobe snd-

DO NOT PRESS ENTER. Press the TAB key twice.
Press y if it asks you if you want to see all results
Look for your soundcard driver. Mine is via82xx, so I found: snd-via82xx.
Success: You found your soundcard driver. Type in the rest of your soundcard driver, and press ENTER.
Type in the Terminal window:

echo "snd-yoursoundcarddriver" | sudo tee -a /etc/modules

Reboot, then open up a Terminal window, and type in it:

aplay -l

Success: You should see your soundcards. Follow the alsamixer section
Failure: *TODO: Add more info*

Failure: You didn’t find your soundcard driver.
Type in the Terminal window:

sudo apt-get install --reinstall linux-sound-base alsa-base alsa-utils

Reboot, then open up a Terminal window, and type in it:

aplay -l

Success: You see your soundcards. Follow the alsamixer section
Failure: You didn’t see your soundcards.
Follow these instructions: http://ubuntuforums.org/showthread.php?t=1681577

Using Alsamixer

Type in the Terminal window:

alsamixer

Success: You should see a nice mixer
To navigate, use the left and right arrow keys
To increase/decrease volume, use the up and down arrow keys, respectively
To mute/unmute, use the M key. Unmuted channels should appear green at the bottom.
To exit, use the Esc key.

To store your settings for the next boot, exit, and type in it:

sudo alsactl store 0

Or if this is your nth sound card (where n is the number of soundcards in your computer) replace 0 with n-1 (so if this is your second sound card, replace 0 by 1).

To test your sound, exit, and type in it (you might have to repeat it a few times):

aplay /usr/share/sounds/alsa/Front_Center.wav

Success: You hear sound
Failure: You do not hear sound.
Follow Check 2

Failure: Follow Check 2

If you had any problems with this guide, feel free to comment below!

Credits:
http://ubuntuforums.org/showthread.php?t=205449
http://ubuntuforums.org/showpost.php?p=1183439&postcount=1