Python & Tkinter – How to embed your application logo in your script

Recently I had the need to create a Windows application (EXE) from a Python script, in order to distribute it to some Windows boxes without Python installed. The script implemented a GUI using  the Tkinter libraries and I even created a cool logo for the app, so I could replace the default Tkinter logo.

The problem was that I would had to distribute the .exe and the logo (.gif) and it seemed kind of weird. So I thought... why not embed the logo in the script? I could use that to create real self-contained GUI apps in a single Python script!

I'll share in this post how I achieved this. It's quite easy.

For this example I've created a very simple logo (64x64 pixels) online using cooltext.com and I exported it in GIF format because it's the appropriated one for this method. Here it is 'mgx.gif':

mgx.gif

We have to insert the bytes of the logo file into a Python variable in the script. The best way to do this is to use a byte encoding that outputs printable ASCII characters, so let's use Base64. You could use many tools to achieve this, I will do it with the base64 command from Linux.

base64 mgx.gif

The command will output the bytes of the .gif encoded.

base64

Now we have to assign the Base64 string to a Python variable. We will use the power of sed and Regular Expressions to make our life easier. Suppose our variable will be called 'logo'.

base64 mgx.gif | sed "s/^/logo += '/g;s/$/'/g"

base64_sed

To get our logo variable set in our Python script we just have to initialize it and then append the previous output.

logo = ''
logo +='R0lGODlhQABAAOf/AAABAAABBQUCBwAEHgQFEQowIHFwIFLQcGGwMFMgwHIQoFRAgHOg0KDwwI'
logo +='KwkKJgoHTA0KNg0LMRIMKQ8JXBQHYxIJVg4NPxcxENRBAOUhUSHxEKfBASMREMdRUPTRUKhBEO'
logo +='bhESWRUUOhkUNR4JlyMIoBgVQRkUbRcPqR0WVRYRwOsgcVuxsUlR4YaiIPvSEZZh8dTxoZhx8X'
logo +='jhUXxiIbgywSySEeeykcfh8Y0RocuSomOygiai8CAcwy4ZvB4grDYV1i8ifiomZioa3ikc1i8g'
logo +='qSsmhy4g0SklsjAjui0nni8pizYjtDUe6zQg4yQkojvi0przUpmjIlzDYj3TAwdjsh7y8sqSkp'
.......

Perfect. Once we have our variable set, the idea is to write those encoded bytes to a file in run time, and tell Tkinter to read that file as the main icon for our GUI. We can create the file in the same directory but I don't like this approach because you don't always have permission to do that. Besides, in my opinion, it's weird to see that a logo appears in the script's folder during execution.

I prefer to write it in a temporary file using the cross-platform library tempfile. Here is the code I used for the example.

iconfile = tempfile.NamedTemporaryFile(mode='w+b', delete=False)
    try:
        iconfile.write(base64.b64decode(self.logo))
    finally:
        iconfile.close()

In the first line we use the method NamedTemporaryFile to obtain a temporary file with a name so we can read it later. We also set the delete option to False because otherwise the file is deleted as soon it is closed. Then, as you can see, we write the bytes we obtain after decoding our logo variable. Finally we close the file.

Just a couple of things before you see the final code. To obtain the real path generated for the temporary file we have to use the name attribute.

if os.path.isfile(iconfile.name):
    icon = PhotoImage(file=iconfile.name)

Finally it's a good practice to tell the OS that we don't need the file anymore when we close our application.

try:
    os.unlink(iconfile.name)
except:
    pass

You can view the whole example here --> embedicon.py

Here are some screenshots of the script in different operating systems.

embedded_xp

Windows XP

embedded_w7

Windows 7

embedded_ubuntu

Ubuntu

embedded_kali

Kali Linux

 

Enjoy :)

Posted on August 21, 2014 at 12:45 by Samuel · Permalink · Leave a comment
In: Languages, Python · Tagged with: , , ,

Kali Gnome Desktop – View Trash and Home icons and delete using the “Delete” key

There are two things that bother me a little when using Kali with Gnome Desktop. There is no Trash icon on the Desktop and the need of pressing ctrl+del to send a file or directory to the Trash. If you feel the same way read the following lines to solve it.

- Showing Trash and Home icons on desktop -

From a terminal type the following:

dconf-editor

The "Configurator Editor" pops up. From the left panel select the following schema:

org >> gnome >> nautilus >> desktop

In the right panel you will see some interesting properties like "computer-icon-visible", "home-icon-visible" and "trash-icon-visible". You have to check them in order to show those icons on the Desktop. If they are already checked and you don't see the icon, uncheck them and check them again.

dconf
kalidesktop

- Deleting using the "Delete" key -

This was a little more painful but I finally found a solution. There is a way by activating the "can-change-accels" property using the dconf-editor utility shown previously, but the problem is that we lose our changes when nautilus is restarted.

So here is the method that worked for me using the console:

Create the folder /root/.gnome2/accels:

mkdir /root/.gnome2/accels

Create the file /root/.gnome2/accels/nautilus and write the following line:

(gtk_accel_path "/DirViewActions/Trash" "Delete")

Save the file. Now restart nautilus:

nautilus -q

That's all.

Enjoy :)

Posted on May 10, 2014 at 12:52 by Samuel · Permalink · Leave a comment
In: Kali, Linux · Tagged with: , , ,

Connecting the Raspberry Pi to an old (or not so) VGA monitor.

I have an old 15 inch VGA monitor optimized for a 1024x768 resolution which I have not used for a while. I thought it would be great to use it with my Raspi because it is quite small size, old and it creates that "retro" atmosphere that I love. But the thing  is not as easy as it may seem. In this post I will explain how I achieved this.

The first thing you need is an adapter to transform from HDMI signal (Raspi output) to VGA signal (Monitor input). The signal must suffer a transformation because HDMI is a digital signal while VGA is an analog one. Be careful with those cheap wires that have just a VGA port in one end and an HDMI port in the other one. They are useless for our purpose. The adapter you need may look like this (please excuse the cat...):

vga_adapter

You can find one of this in many sites, Amazon or eBay for example. I  bought this one for around 12 €. This model is great because it has also a jack port to get the sound that may come from the HDMI signal. So this is my Raspi connected to the old monitor using the adapter I got:

Raspi using HDMI to VGA adapter

Now when you turn on your Raspi three different things could happen:

1) You see everything perfectly in your VGA monitor. You are a very lucky person and you are probably wondering why I am writing this post.

2) You see a resolution that is not good for your monitor or that you do not want and you cannot change it.

3) You do not see anything in your monitor.

If your case is not the first one there is work to do yet. By the way, in my case it was the second one using Raspbian and the third one using Berryboot. I will be using the Raspbian example. When I turned on my Raspi I got a message from my monitor saying that it had to use a 1280x720 "failsafe mode" resolution which did not look very good:

1280x720, not proper resolution

I lost like a third of the screen using this resolution and the image and text quality was very poor. There was no way to change this resolution dynamically.

So now is the time to introduce the Raspberry's config.txt file. This file performs a basic configuration  when you turn on your Raspi and change its parameters would be like tuning the BIOS in a normal PC. So this file is the key to get our monitor working properly.

The config file is located at /boot/config.txt but if your case is the third one, and you cannot see anything on the screen, you can read the SD card in other PC and you will find the file at /.

You can find all the details, parameters and configurations for this file at:

http://elinux.org/RPiconfig

The problem is that setting the right parameter values depends on your hardware; your monitor, your hdmi-vga adapter and even your wire! You can spend much time tuning this file but here is the trick that worked for me:

There is one parameter called hdmi_safe that when enabled (hdmi_safe=1), it sets the proper parameters to maximize compatibility for HDMI. Reading from the RPIconfig site above:

hdmi_safe Use "safe mode" settings to try to boot with maximum hdmi compatibility. This is the same as the combination of: hdmi_force_hotplug=1, hdmi_ignore_edid=0xa5000080, config_hdmi_boost=4, hdmi_group=2, hdmi_mode=4, disable_overscan=0, overscan_left=24, overscan_right=24, overscan_top=24, overscan_bottom=24

If you type (or uncomment in some config.txt files) hdmi_safe=1, save and reboot you should boot using a 640x480 resolution:

640x480 proper but too low

Ok. That is a low resolution but it looks much better. So this "hdmi_safe" parameter did a good job. Now, to be sure of which parameters have been set, let's use a couple of commands again from the RPiconfig site:

vcgencmd get_config int - lists all the integer config options that are set (non-zero)
vcgencmd get_config str - lists all the string config options that are set (non-null)

In my case "vcgencmd get_config int" returned the following:

hdmi_safe=1
hdmi_mode=4
hdmi_group=2
hdmi_force_hotplug=1
disable_overscan=1
overscan_left=24
overscan_right=24
overscan_top=16
overscan_bottom=16
program_serial_random=1
config_hdmi_boost=4
hdmi_ignore_edid=0xa5000080
temp_limit=85
force_pwm_open=1

And "vcgencmd get_config str" did not return anything.

Therefore the group of parameters enabled do not match the ones RPiconfig indicates when hdmi_safe is activated. That's why I recommend to use vcegencmd command, to be sure of which parameters are really set. Now the only thing left to do is to change the 640x480 resolution to 1024x768 and remove the "padding" you can see in the image above.

The resolution has to be with the "hdmi_mode" parameter, and you can see its possible values in the RPiConfig site. I will show some of them:

hdmi_mode=1 640x350 85Hz
hdmi_mode=2 640x400 85Hz
hdmi_mode=3 720x400 85Hz
hdmi_mode=4 640x480 60Hz
hdmi_mode=5 640x480 72Hz
hdmi_mode=6 640x480 75Hz
hdmi_mode=7 640x480 85Hz
hdmi_mode=8 800x600 56Hz
hdmi_mode=9 800x600 60Hz
hdmi_mode=10 800x600 72Hz
hdmi_mode=11 800x600 75Hz
hdmi_mode=12 800x600 85Hz
hdmi_mode=13 800x600 120Hz
hdmi_mode=14 848x480 60Hz
hdmi_mode=15 1024x768 43Hz DO NOT USE
hdmi_mode=16 1024x768 60Hz
hdmi_mode=17 1024x768 70Hz
hdmi_mode=18 1024x768 75Hz
hdmi_mode=19 1024x768 85Hz
hdmi_mode=20 1024x768 120Hz
hdmi_mode=21 1152x864 75Hz
hdmi_mode=22 1280x768 reduced blanking

...(truncated)

As you can see the hdmi_safe configuration used hdmi_mode=4 which corresponds to a 640x480 60Hz resolution. I will change this value to 16 that corresponds to 1024x768 60Hz which is perfect for my monitor. As you can imagine, the "padding" thing has to be with the "overscan_left", "overscan_right", "overscan_top" and "overscan_bottom" parameters. If you see my config, it is curious that  the "disable_overscan" is set and the overscan is working. I will set the four parameters I mentioned to 0 because I do not need any padding. My final configuration will be the following (remember that now we have to disable the hdmi_safe parameter):

hdmi_safe=0
hdmi_mode=16
hdmi_group=2
hdmi_force_hotplug=1
disable_overscan=1
overscan_left=0
overscan_right=0
overscan_top=0
overscan_bottom=0
program_serial_random=1
config_hdmi_boost=4
hdmi_ignore_edid=0xa5000080
temp_limit=85
force_pwm_open=1

Now I am ready to set or copy this parameters to the config.txt file and reboot. Everything looks great and now my monitor starts a new life working with my Raspi.

1024x768 perfect

1024x768 desktop

I hope this post can help you out.

Enjoy.

Posted on November 17, 2013 at 21:21 by Samuel · Permalink · 14 Comments
In: Raspberry Pi, Raspbian · Tagged with: , , ,

Recovering router password using Burp Suite dictionary attack

Few weeks ago, during cleaning up, I found an old access point/router. I wanted to attach it to my network and do some tests, but I did not remember the password for configuring it through its web access page. I knew it had to be some default user/password but I did not succeed in my tries. I thought it was the right time to prepare a small dictionary attack. There are many powerful tools for this task but I used "Burp Suite" because I love it and I try to use it whenever I can. Furthermore is a perfect tool for understanding what happen behind the scenes during these kind of attacks.

I made the following video trying to explain this process. I hope you find it helpful.

If you want you can download the 'combinator' script used in the video -> combinator.rb.

Enjoy.

 

Posted on August 26, 2013 at 23:08 by Samuel · Permalink · 5 Comments
In: Backtrack, Blackbuntu, Kali, Linux, Windows · Tagged with: , , , ,

TP-LINK TL-WN725N v2 working on Raspberry Pi (Raspbian)

When I bought my Raspberry Pi I also ordered this tiny usb wifi adapter (TP-LINK TL-WN725N) in order to play with my raspi everywhere. I got this adapter because  I read it worked out of the box, it was cheaper than others and it supported WiFi-N. As you may guess I am writing this post because the first advantage, the out of the box one, did not work for me.

Raspi with TP-LINK WN725N

I read some forums and it seemed that I had purchased a newer version of this adapter, the TL-WN725N v2. It needs a different driver, the Realtek 8188eu, which is not included by default in the Raspbian distributed by the official web site of Raspberry Pi. So, to sum up, I was able to find the driver source code and now I have a wireless raspi. If you have the same problem with this adapter, read the following lines to obtain directly the .ko object and you will be done. If you want you can download the driver source code (link at the end), compile and install it on your own.

To make it work just download the kernel object (.ko) file which is the compiled module driver for the kernel. I will be updating this section for different kernel versions.

For raspbian image: 2013-07-26-wheezy-raspbian.img
8188eu.ko (Compiled in 2013-08) (Working in kernel Linux raspberrypi 3.6.11+ #474 PREEMPT)

For raspbian image: 2013-09-25-wheezy-raspbian.img
8188eu.ko (Compiled in 2013-10) (Working in kernel Linux raspberrypi 3.6.11+ #538 PREEMPT)

For raspbian image: 2013-12-20-wheezy-raspbian.img & 2014-01-07-wheezy-raspbian.img
8188eu.ko & firmware (Compiled in 2014-01) (Working in kernel Linux raspberrypi 3.10.24+ #614 PREEMPT & 3.10.25+ #622 PREEMPT)

For raspbian image: 2014-06-20-wheezy-raspbian.img
8188eu.ko & firmware (Compiled in 2014-06) (Working in kernel Linux raspberrypi 3.12.22+ #691 PREEMPT)

For raspbian image: 2014-09-09-wheezy-raspbian.img
8188eu.ko & firmware (Compiled in 2014-09) (Working in kernel Linux raspberrypi 3.12.28+ #709 PREEMPT)

For raspbian image: 2014-12-24-wheezy-raspbian.img
8188eu.ko & firmware (Compiled in 2014-12) (Working in kernel Linux raspberrypi 3.12.35+ #730 PREEMPT)

Place the .ko object in the following path:

/lib/modules/(your-kernel-version)/kernel/drivers/net/wireless

In my case it is the following path:

/lib/modules/3.6.11+/kernel/drivers/net/wireless

Last version of the rtl8188eu driver includes a firmware file called rtl8188eufw.bin you have to place this file under:

/lib/firmware/rtlwifi/

Now execute the following commands

depmod -a

modprobe 8188eu

We are done. You should see now the new interface (wlan0 normally) when the device is connected.

Driver source code: https://github.com/lwfinger/rtl8188eu

Enjoy.

 

Posted on August 16, 2013 at 13:05 by Samuel · Permalink · 182 Comments
In: Linux, Raspberry Pi, Raspbian · Tagged with: , , , ,

HTC Desire Mildwild CM-5.0 Transparent Status Bar

As Mildwild CM-5.0 is one of the best roms I've ever used and the one I'm using right now, there is one customization that I'm accustomed to and it's not available, the transparent status bar. Searching on the net I finally found a guide (link at the end) which explains how to do it on Cyanogenmod 7.0.3 and because this version of Mildwild is based on Cyanogenmod 7.2 we can get it to work with a few changes. I'll explain in the following lines how I applied this customization on my HTC Desire GSM. The method is not dangerous but, if you are not sure about what you're doing,  backup every file you change.

The first thing is to install a launcher that supports this option. I like "Go Launcher" but you can use others (e.g. ADWLauncher). In "Go Launcher" you can find this option inside "Preferences" - "Advanced settings":

Transparent Status Bar Option

 

Now, as the warning says, we have to "make sure that our system has the transparent status bar!".

We have to copy the file /system/app/SystemUI.apk to our computer. Use the method of your choice, sdcard-usb-computer, email, dropbox ...

Open it with a compression/decompression tool like winzip, rar, 7zip.. I'll use winRAR.

Extract the file /res/drawable-hdpi/statusbar_background.9.png (pay attention to the name because there are others very similar) and open it with an image manipulation tool like Photoshop or GIMP. Apply transparency to the image. You can make it 100% transparent if you want. I applied 20% of opacity (80% transparent).

Ok, that was easy. Next step.

Extract the file /classes.dex from SystemUI.apk. This is a compiled file for android. We have to decompile it, edit it and compile it again. For this purpose we need the tools baksmali and smali. You can download them from the following links:

baksmali smali

or from http://code.google.com/p/smali/downloads/list

Put these tools in the same folder as the classes.dex file and open a command line terminal.

Run this command:

java -jar baksmali-1.3.3.jar -o classout/ classes.dex

The folder classout has been created, open it. Edit the file com/android/systemui/statusbar/StatusBarService.smali with a text editor. Find the text "new-instance v0, Landroid/view/WindowManager$LayoutParams;". I can find it in line 2210. Eight lines after this text we can find "const/4 v5, 0x2". We have to change 0x2 to -0x3. So the line will be:

const/4 v5, -0×3

We're done with the edition, save and close the file.

Now run this command to compile the file again:

java -jar smali-1.3.3.jar classout -o classes.dex

Ok, done. So far we have modified two files: statusbar_background.9.png and classes.dex. Now we have to put these files in the place they were inside SystemUI.apk, replacing the original ones. Use again the compression/decompression tool to perform this task.

The next step is to move our modified SystemUI.apk file to the sdcard. Again use the method you want; usb, email, dropbox... etc. Place it for example in the root of the sdcard.

The last step is to replace the SystemUI.apk that is running on your phone by the one we've modified. As we have to write in /system partition, which is mounted with read-only permissions, we need to remount it with writting permissions. For this task we need to use a Terminal on the Android device. If you don't have one, get it from the market.

On the Terminal, run these commands:

su root

* I'll suppose that you've copied the modified SystemUI.apk in the root of the sdcard, if you haven't, change the path appropriately in the following command:

cd /sdcard/

mount -o remount,rw /system/

cp -f SystemUI.apk /system/app/

With this last command, the launcher usually crashes someway. In my case my status bar dissapear. You need to restart the phone.

After reboot you should have the status bar with the rate of transparency you've chosen:

Transparent Status Bar Working

I'm sure the previous steps (maybe with some modifications) can get transparent status bar working on other devices and versions. Just play a litte.

Original source: http://www.lazytrap.com/?p=314

Enjoy :)

Posted on September 2, 2012 at 18:56 by Samuel · Permalink · 2 Comments
In: Android, CyanogenMod, Mildwild · Tagged with: , , ,

Blackbuntu: Failed to fetch http://deb.torproject.org/torproject.org/dists/maverick/…

If you're using Blackbuntu nowadays you might have found the following error lines when you execute apt-get update:

W: Failed to fetch http://deb.torproject.org/torproject.org/dists/maverick/main/source/Sources.gz 404 Not Found

W: Failed to fetch http://deb.torproject.org/torproject.org/dists/experimental-maverick/main/binary-i386/Packages.gz 404 Not Found

The thing is that maverick is not longer supported in the tor's repositories and it's been replaced by lucid. So we have to do the same in order to fix it:

nano /etc/apt/sources.list

Now go to the TOR repositories section and replace the following lines:

# Tor Project
deb-src http://deb.torproject.org/torproject.org maverick main
deb http://deb.torproject.org/torproject.org experimental-maverick main

with these lines:

# Tor Project
deb-src http://deb.torproject.org/torproject.org lucid main
deb http://deb.torproject.org/torproject.org experimental-lucid main

Now finally execute:

apt-get update
apt-get upgrade

Done.

Enjoy!

Posted on July 1, 2012 at 09:34 by Samuel · Permalink · 3 Comments
In: Blackbuntu · Tagged with: , ,

Enabling sshd in Backtrack 5

By default sshd is not enabled in Backtrack 5 but of course is installed.

Just run this command:

sshd-generate

And now we can start the service, choose one of the following ways:

 service ssh start

/etc/init.d/ssh start

start ssh

Done. Service is listening on port 22. You can access using root/toor.

You can change the configuration by editing /etc/ssh/sshd_config.

 

Enjoy.

Posted on March 26, 2012 at 18:42 by Samuel · Permalink · Leave a comment
In: Backtrack, Linux · Tagged with: , ,

Customize single cells in JTable

JTables are very useful for develop desktop applications but when it comes to customize properties at cell level it can be a little tricky. The key concept here is that we have to deal with Cell Renderers for each column. TableCellRenderer is an interface that forces to implement the following method:

Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)

The most common way to customize Cell Rendering is to create a class that extends a Component and implements TableCellRenderer. Most people use a simple JLabel. For example,  the following class will allow us to change the background of a single cell:

public class JLabelCellRenderer extends JLabel implements TableCellRenderer
{
  @Override
  public Component getTableCellRendererComponent(JTable table,Object value,
  boolean isSelected,boolean hasFocus, int row,int col)
  {
    JLabel label = (JLabel) value;
    setBackground(label.getBackground());
    setOpaque(true); /* Important to see the background color */
    return this;
  }
}

Now lets create our table and use our custom cell renderer:

JTable table = new JTable();
String[] columnNames = {"Red","Blue"}; /* Two columns */
JLabel[][] data = new JLabel[1][2]; /* One row, two columns */
data[0][0] = new JLabel("");
data[0][0].setBackground(Color.red);
data[0][1] = new JLabel("");
data[0][1].setBackground(Color.blue);
table.setModel(new DefaultTableModel(data, columnNames));
/* Now we use our new class for rendering cells */
table.getColumnModel().getColumn(0).setCellRenderer(new JLabelCellRenderer());
table.getColumnModel().getColumn(1).setCellRenderer(new JLabelCellRenderer());

Now we put it in a JFrame and the result is the following:

JTable 2 cell colors example
So it worked! Now you can improve the cell renderer and get more properties from the JLabel such as Font, Foreground, Border... etc.
I've developed a more complex but funnier example in which I've used most common methods and properties to customize the aspect of a JTable. A couple of screenshots are shown below so you can get the idea.

JTable example serious JTable example smiling

 

You can get the source code -> Smiley.java

and the executable jar file -> Smiley.jar

Enjoy.

Posted on February 11, 2012 at 12:14 by Samuel · Permalink · Leave a comment
In: Java, Languages · Tagged with: ,

Unsupported major.minor version 51.0

The other day I was trying to compile and run some swing example code using the command line and when I tried to execute I got the following error:

Exception in thread "main" java.lang.UnsupportedClassVersionError: Main : Unsupported major.minor version 51.0

I found on the Internet that version 51.0 corresponds to java 1.7 and then I realised that I have jdk 1.7 installed while my jre is 1.6.

I usually don't care about this compatibilty issues because NetBeans takes care of this.

So the solution is to tell javac to compile it for 1.6:

javac -source 1.6 -target 1.6 MyClass.java

And then it worked like a charm.

NOTE:

This kind of error is due to version differences between the binaries and the virtual machine and can be solved like I wrote above. Having said that remember that if you have some incompatible source code between versions javac compiler will complain.

Enjoy.

Posted on February 9, 2012 at 09:27 by Samuel · Permalink · Leave a comment
In: Java, Languages · Tagged with: