Jan 21, 2013

Compile Android 2.3.3 in Slackware 14

I. Introduction:
Recently I decided to change my linux distro from ubuntu to slackware. The installation process is nice and smooth. After I install slackware, I decided to download the android 2.3.3 source and compile myself. I have done it before in ubuntu 10.04, so I told to myself how hard could it be. However I was wrong, compiling android in slackware 14 is incredibly annoying. Most of the problems are caused by gcc and perl version mismatch. Some people might say, just downgrade/upgrade your gcc/perl version and it should be fine. I know that, but changing gcc/perl version in your system might cause some problems and I don't want to take that risk. (btw, recompile gcc is very time consuming in my computer. Hardware sucks) 
Because the above reason, I decide to compile the android 2.3.3 without downgrade any tools and also to write the whole process down to remind myself how I do it.

II. Environment:

  • Linux Distro : Slackware 14 x86_64( with multilib support )
  • gcc version : 4.7.1
  • make version : 3.82
  • perl version : 5.16
  • git version : 1.71
  • python version : 2.73

Just a clean install of slackware 14.
As for multilib support just check out Alien BOB wiki and follow the instructions that wiki mentioned. 
P.S you should at least have >2GB of RAM or the building process may failed. 


III. Compiling Steps:
This post is mostly focus on how to solve the version mismatch problems; therefore, I will not cover how I setup the build environment in this post. (Most libraries that required to build android are already installed by the Slackware 14 clean install)
After you follow the ASOP instructions and install all the necessary packages, it is time to type make command. (I highly recommend that use 'make -j1' instead of 'make -j8' )

1. GCC version mismatch:
The following is an example of how this kind of error message look like and the general solutions of how to solve this kind of problems. Figure 1 shows how this kind of error message looks like. There are two ways to solve this kind of problem. 
The first one is add "this->" in front of all the variables that appear in the error message. However, in the entire building process, you will be very annoying adding this pointer in front of all the errors.
The second method is to add  "-fpermissive" flag in the makefile. More precisely add "-fpermissive" to LOCAL_CFLAGS in Android.mk. This method is more reasonable. 
During the whole building process, there are several Android.mk files that need to be modified (adding "-fpermissive" flag)


frameworks/base/tools/aapt/Android.mk
frameworks/base/libs/utils/Android.mk
external/srec/tools/grxmlcompile/Android.mk
external/srec/tools/thirdparty/OpenFst/fst/lib/Android.mk
external/srec/tools/make_cfst/Android.mk
external/v8/Android.mksnapshot.mk

 
[figure 1] gcc version mismatch error message
[Figure 2] Add "-fpermissive" after the LOCAL_CFLAGS in the Android.mk

2. perl Switch module problem:
Switch.pm is deprecated in perl 5.16, therefore the solution is simple, patch the "external/webkit/WebCore/dom/make_names.pl". Figure 4,5,6 show some modification of this file. 
[Figure 3] Can't locate Switch.pm
[Figure 4] comment use Switch
[Figure 5] use if else instead of switch case


[Figure 6] delete the "-P" flag from preprocessor
IV. Conclusion:
After the above steps, the building process should be fine and you can see the image file in the out directory.
I also make a diff file which you can download from here: http://pastebin.com/RCfB5irk
Just download the file and type:
patch -p1 < patch_file_name.patch
Enjoy :)

Linux Kernel 1: How to Compile Linux Kernel

I. Introduction:
This post is the first post for linux kernel hacking. Before you can dig into linux kernel source you should first learn how to build a kernel yourself.
There are many distributions out there, and I prefer to use Slackware 14, gentoo or debian (not dibian based distro such as ubuntu, mint). The reason I recommend to use these two distro is because that most modern distributions have changed so many linux codes that may confused you while your are tracing linux code.

II. Environment:
  • Linux Distro: Slackware 14 x86_64
  • kernel version: 3.2.37
  • gcc version: 4.7.1
III. Contents:
1. pre-requirement:
The first thing you should do is download the kernel source that you want to build. The kernel source file can be found in : http://www.kernel.org/pub/linux/kernel/.
In my case, "linux-3.2.37.tar.bz2". Just extract the file and put it into the directory that you want. I put the source code in "$HOME/kernel/".


2. config:
Before building the kernel, you have to config it first.  type "make help" and you can see a list of options. In this part, we just focus on the config sections.
The following  are some options that are commonly used.



config          - Update current config utilising a line-oriented program
menuconfig      - Update current config utilising a menu based program
xconfig         - Update current config utilising a QT based front-end
gconfig         - Update current config utilising a GTK based front-end
oldconfig       - Update current config utilising a provided .config as base
localmodconfig  - Update current config disabling modules not loaded
localyesconfig  - Update current config converting local mods to core


The description is very self-explained therefore I'm not going to explain it. Just a quick note, if you prefer the GUI interface, type "make xconfig/gconfig" which will give you gui interface to config the kernel. In my case I use "make localmodconfig" which will set the config file according to your system modules.

------------------------------------[update]---------------------------------------------------------
 you can also use "gcat /proc/config.gz > .config" if your previous kernel has enable the IKCONFIG  and IKCONFIG_PROC flag. This will copy the previous kernel configuration to your current kernel source. After you finished the above command you can still type "make oldconfig" if you are using a newer kernel. (The newer kernel may have some new features )
Thank you +Eric Garland. :)


3. build the kernel:
If this is the first time you compile this kernel Type "make all -j8" to compile the kernel. The "make help" output tell us that the make install will build the target marked * and the default one is "vmlinuz" and "modules".
However, if u have compiled the kernel before and there is no new featured that is added in the config file.You can type "make vmlinuz -j8" instead. It will only build the vmlinuz and will not build the modules.
If you have add a new modules or edit the modules source code you can type "make modules -j8" to only compile the linux modules.
P.S Compiling the linux kernel may take some time according to your hardware. (get a cup of coffee or watch a movie :P)

4. Install the modules:
If this is the first time you build the linux kernel: type "sudo make modules_install". If your haven't modify any kernel modules or add a new one in the config file, this step can be skiped.


5. Install the kernel:
Instead of typing "make install" I prefer using the following command.


sudo cp arch/x86_64/boot/bzimage /boot/vmlinuz-3.2.37
sudo mkinitrd -c -k 3.2.37 -m ext4 -f ext4 -r /dev/sdaN -o /boot/initrd-3.2.37.img


More detailed about mkinitrd command, type "man mkinitrd" or check out this link: http://mirrors.slackware.com/slackware/slackware-11.0/extra/linux-2.6.17.13/README.initrd


6. Update your bootloader:
Since I'm using slackware and the default bootloader of slackware is lilo, so I have to edit the /etc/lilo.conf. After modified the /etc/lilo.conf type "sudo lilo".


7. Command Walk through:

        // if this is the first time you compile the kernel
make mrproper;
// if this is the first time you compile the kernel or want to add some new features to your kernel.
make localmodconfig/menuconfig/xconfig/gconfig;
make all && make modules_install; // if this is the first time you compile the kernel or adding new stuff to the
make vmlinuz; // if you just change the kernel source
make modules && make modules_install; // if you have add a new module in config file or modify the module source code
cp arch/x86_64/boot/bzimage /boot/vmlinux-3.2.37
mkinitrd -c -k 3.2.37 -m ext4 -f ext4 -r /dev/sda2
-----update your bootloader----
echo "done";



IV Conclusion:
This is basically how to compile a linux kernel. I will talk about some more configuration and some tools to help you trace the linux code. Happy Hacking.

Oct 3, 2012

Ubuntu 12.04 notes.

Ubuntu 12.04 has been released for a while. I recently installed this version and almost everything works great except the video and wireless driver. I have google for a very long time and viewed many threads to solve these two problems. Therefore, this post is just to remind me how I solved this problem.

Video Drivers:

My notebook's graphic card is ati radeon hd 4300. If you want to check what graphic card your computer is using just type:

lspci -vnn | grep VGA

and it will show you the information that you need.
Actually, there are many ways to install the graphic drivers. The following is just how I set my video drivers.
First make sure you haven't installed an old fglrx drivers. If you do, simply type:

sudo apt-get remove --purge fglrx* fglrx_* fglrx-amdcccle* fglrx-dev*

this command will remove the fglrx driver that your system is currently using.
After remove the old drivers, download the binary file from the amd support web site:
In my case, the binary file I need to download is as follow. http://support.amd.com/us/gpudownload/windows/previous/12/Pages/radeon_linux.aspx?os=Linux%20x86&rev=12.4
After download the binary file type:

chmod +x amd-driver-installer-12-4-x86.x86_64.run
./amd-driver-installer-12-4-x86.x86_64.run --buildpkg Ubuntu/precise
sudo dpkg -i *.deb

That's it. Reboot your system and the fglrx should installed properly.
More detailed, check the following two reference websites.
https://help.ubuntu.com/community/BinaryDriverHowto/ATI
http://askubuntu.com/questions/124292/what-is-the-correct-way-to-install-ati-catalyst-video-drivers

Wireless Drivers:

My notebook's wireless NIC is Broadcom BCM 4312. Again, if you want to know what chipset your device is using type:

lspci -vnn | grep Network

And it will print out the information you need. After knowing the chipset, it's time to find out what kind of driver/module that I need. Actually, installing the new wireless driver is very simple in ubuntu 12.04. Just type sudo apt-get install backport-module-cw-$kernel_version the kernel_version is your kernel version which can use uname command to verify it. After this instruction, it will install almost all the wireless module(atheros or broadcom chipset) from newer kernel version. Hope this post can help others. :)

May 19, 2012

windows shellcode 1: Introduction

Ok, this is another shellcode tutorial. However, this time I'm gonna focus on windows shellcoding technique.

In the previous shellcode tutorial, I'm using linux as my environment. After research and google for a while, I think it's time to write something about windows shellcode.

The most significant difference between linux shellcode and windows shellcode is that when writing linux shellcode we use system call to achieve the goal we want. However, in windows, the system call will various in different version. Therefore, when writing windows shellcode, we have to use windows API to achieve the goal.

There are several  ways to get the windows API address and the most simple one is using GetProcAddress() and LoadLibraryA() in kernel32.dll.
I use the following C program to demonstrate how to use these two API.


#include <windows.h>
#include <stdio.h>
int main() {
    unsigned int api_addr = 0;
    api_addr = GetProcAddress(LoadLibraryA("kernel32.dll"), "ExitProcess");
    printf("address 0x%x\n", api_addr);
}

In the above example the api_addr will contains the virtual address of ExitProcess().
P.S You can get more information of windows API in MSDN.

After knowing the address of ExitProcess, it's time to write a simple shellcode that will exit the program.

.global _main
_main:
    pushl $0;
    movl $0xdeadbeef, %ebx;
    call *%ebx;

In the above assembly code, you have to change the $0xdeadbeef to the API address the previous C program output to you. And the reason why using call *%ebx instead of call $0xdeadbeef is that when using call $0xdeadbeef the assembler will compile the code into a relative call instead of a direct call; therefore the result may not be what we are expected. I have mentioned this in the previous post. If you want u can check here.
http://mike820324.blogspot.com/2011/05/shell-code.html

This post is only a brief introduction of windows shellcode, I will post more advanced technique and shellcode later these days.

May 15, 2012

Some Great Python Tools

Recently, I start to learn python since it is very convenient and powerful. And I'm gonna introduce some great python tools that will be very helpful in the future work.

1. pip
The first one is pip. It is a tool that will help you managing the python packages. A great replacement for easy_install, but more powerful.
In Ubuntu, you can simply install pip by typing
sudo apt-get install python-pip

or you can download the package from the following link
http://pypi.python.org/pypi/pip#downloads
untar the file and type
sudo python setup.py

U can use pip to install python package either from web site or tar files.
type
pip search $PACKAGE_NAME
and it will search the package 4 u.

simply type
pip install $PACKAGE_NAME
will help u install the package to your system.


2. virtualenv & virtualenvwrapper
The second tool I'm gonna introduce is virtualenv. It is a tool to help u creating a virtual python environment to solve the consistency problem.
In Ubuntu, simply type
sudo apt-get install python-virtualenv

or u can use pip to help you install virtualenv, just type
sudo pip install virtualenv

And if you have many projects that need to be managed, virtualenvwrapper is a very good choice. The tools contains some wrapper function from virtualenv and help u ease your job.

If u want to get familiar with virtualenv and virtualenvwrapper the following links are some good tutorials about these tools.
http://mathematism.com/2009/07/30/presentation-pip-and-virtualenv/
http://www.doughellmann.com/articles/pythonmagazine/completely-different/2008-05-virtualenvwrapper/index.html
http://simononsoftware.com/virtualenv-tutorial/

3. scapy
scapy is a very powerful tool for packet manipulation and packet sniffing. If you want to play with packets and learn some internet protocols or doing some internet forensic or pen-testing it is a very useful tools. The official documentation is great start to learn scapy. I will also post some tutorial of how to use scapy in the future.
http://www.secdev.org/projects/scapy/doc/index.html
http://fossies.org/dox/scapy-2.2.0/annotated.html
http://www.secdev.org/projects/scapy/

want to install just type
sudo pip install scapy
or
sudo apt-get install python-scapy

4. Django or Pyramid
Django and Pyramid are both high-level web framework for programmers to develop their own web project in a rapid way. In short, they are "ruby on rails " in python :P
Even though both tools can help people organize their web framework, but they are still different.
The comparison of these two framework can be found in these links.
http://stackoverflow.com/questions/48681/pros-cons-of-django-vs-pylons
http://xiaonuogantan.wordpress.com/2011/12/24/pyramid-vs-django/
http://www.slideshare.net/whykay/python-ireland-may-2011-what-is-pyramid-and-where-is-it-with-respect-to-django-by-kevin-gill
There are still more, you can just google for that.

Here are some links that will help u dig deeper in Django.
https://docs.djangoproject.com/en/1.4/
http://www.djangobook.com/en/2.0/

And also some links for Pyramid
http://docs.pylonsproject.org/en/latest/docs/pyramid.html

5. Scrapy
Scrapy is a high-level python web crawling framework. If you want to design some web robot or web spider, Scrapy is a good choice.

The documentation of scrapy is right here
http://scrapy.org/doc/

want to install just type
sudo pip install scrapy
or
sudo apt-get install python-scrapy

Dec 27, 2011

What the hell is "NetCut" doing and how to prevent

NetCut is a program that will help you disconnect other computers in the same subnet of an ethernet network. You can download the program from this link: NetCut.
In this post I will describe the technical detail about NetCut and how to prevent this kind of program/attack.

I. Technical Detail About NetCut:
NetCut use a simple technique called "ARP poisoning" or sometimes called "ARP spoofing". It is a attack technique usually used to trigger an Man In The Middle attack. Before introducing the ARP poisoning, we have to know what is ARP.
ARP is the abbreviation of Address Resolution Protocol. According to wiki, "ARP is a protocol used for resolution network layer address to link layer address." That is, ARP will map the IP address of a machine to it's MAC address.
Consider the following LAN from Fig. 1:

<figure 1> Local Area Network Example

Now If Alice want to send a Packet to Bob, Alice machine will check if the MAC address of IP 192.168.0.3 is exist in the ARP cache table. If it is not exist in the table, it will broadcast a ARP request asking for the MAC address of 192.168.0.3. While Bob's machine receive the broadcast message, it will reply it's MAC address to Alice. Fig. 2 shows the communication process.

<figure 2> ARP communication process

After knowing the ARP, it's time to introduce the "ARP poisoning attack". Consider the following condition. What if Evil reply the ARP request before Bob when Alice broadcast the ARP request. In this scenario, Alice's machine will think that the MAC address of IP 192.168.0.3 is 00:00:00:00:00:03(MAC address of Evil), instead of 00:00:00:00:00:04(MAC address of Bob). Therefore, Alice will send the packet to Evil instead of Bob.Fig. 3 shows the process of this attack.

<figure 3> ARP posioning attack
What if Evil send the ARP reply with a non-exist MAC address of the gateway, then Alice's machine will become a DoS condition. This is how NetCut disconnect other computer in the same subnet.

II. Prevention of ARP poisoning:
The best way to prevent your computer being poisoned is use a static ARP instead of dynamic. In both windows and linux system, there is a command called arp which can let you check the arp cache table and moreover change the dynamic table into static.
You can also installed some application such as arpwatch in unix and Xarp-v2 in winodws to defense this kind of attack.

III. reference website:
ARP and ICMP redirection
arp-spoofing wiki

Dec 26, 2011

What can you do when linux is not responding

Linux is a very stable system compare to windows(:P). However even it is very stable, it will still crash sometimes.
So what can you do if the system is crashed.

1. go to the tty:
Sometimes, it is the graphic mode crash but the linux kernel and other critical process are still alive.
If you have encounter this situations, There is no need to reboot your system.
Instead, you can goto tty to fix the problem.
In linux system you can go to tty by pressing [ctrl]+[alt]+[f1~f7].
The default graphic mode is in tty7, that is you can press [ctrl]+[alt]+[f7] to return to graphic mode.
A tty is a pure command prompt and you can restart the x-server from here.
ubuntu 11.10 use lightdm, so I take lightdm as an example.
type the following command:
sudo /etc/init.d/lightdm restart
that's it, and you will see the graphic mode is restarted.

2. the magical sysrq:
If your system crash and the keyboard has no respond, it's time to use the sysrq.
What is a sysrq, it is a little button on your keyboard. Normally, it is near the delete key .  If your system crash, and you can not enter the tty mode. Try the following combination keys:
[alt]+[sysrq]+[R]-> [alt]+[sysrq]+[E]-> [alt]+[sysrq]+[I]-> [alt]+[sysrq]+[S]-> [alt]+[sysrq]+[U]-> [alt]+[sysrq]+[B]
If everything works fine, your system will reboot but will save some files and safely kill the process that you are working on.
So what the hell is going on under these combination keys?
The following show you the functionality of each keys.

a. [alt]+[sysrq]+[R] : turn your keyboard into ascii mode, it enables your keyboard to send message to the kernel directly.
b. [alt]+[sysrq]+[E] : send SIGTERM signal to all the process except the init process.
c. [alt]+[sysrq]+[I] : send SIGKILL signal to all the process except the init process. This will kill all the processes except the init process.
d. [alt]+[sysrq]+[S] : sync the buffer pool to the hard disk, in case to lose datas.
e. [alt]+[sysrq]+[U] : remount all the mounted-filesystem to read-only.
f. [alt]+[sysrq]+[B] : reboot the system.
p.s while using the combinations, use it slowly. :P
That is, after using the first combination, wait about 5 secs and then use the second one and so on. If you use the combinations too quick it is no difference than press the power key. 
The recommend wait time is:
R--1 sec-- > E--30 sec --> I-- 10 sec --> S --5 sec --> U -- 5 sec --> B

If you want to know more detailed about the sysrq the following link has a very good explanations.
English version:
Magic sysrq
Chinese version:
https://www.deleak.com/blog/2010/10/20/sysrq/

Ubuntu 11.10 Notes

It's been a really long time that I haven't write a new post. My school work is fucking busy.
I have installed ubuntu 11.10 for a while. I decided to write some note about the installation and configuration process.

Installing ubuntu 11.10 is quite easy, just put the disk into the computer, follow the steps and yes you have installed your ubuntu 11.10.

1. video drivers:
I'm using ATI video cards, and meet some problem while using the default video drivers.
There are many solution of this problem. I just post the solution I used:
First, go to AMD official website and download the video device dirver.
The one I'm using is "ati-driver-installer-11-11-x86.x86_64.run"
and type the following command and reboot, and the video driver is installed.
mkdir ati-11.11;
cd ati-11.11
wget www2.ati.com/drivers/linux/ati-driver-installer-11-12-x86.x86_64.run
sh ati-driver-installer-11-11-x86.x86_64.run --buildpkg Ubuntu/oneiric
dpkg -i fglrx*.deb
aticonfig --initial -f

If you still meet some problems, the following websites maybe a good place
to search your solutions.
x/troubeshooting
ubuntu install guide
ubuntu+gnome shell+ati driver
gnome shell doesn't work properly

2. Installing some applications
   a. upgrade the app: type the following command and upgrade the applications that already install in the system.
   sudo apt-get update && sudo apt-get upgrade

   b. install the restricted packages: this will enable you to play some popular music/video formats such as mp3 and so on. Type the follwoing command:
   sudo apt-get install ubuntu-restricted-extra

   c. enable full dvd play back: After that you can watch videos from dvds.
   The instruction is too long, so I post the original link and you can follow the instructions from those websites.
   install libdvdcss
   15 things I did...

   d. and more: There are still more applications you may want to installed. Reference this link:
   Best applications and tweeks ....

This is pretty much about it.

Dec 9, 2011

wargame competition Taiwan

You can download the questions in the following link:
wargames


However the archive file is encrypted, if u want the key please send me an email.
mike820324@gmail.com

Description of each questions is listed in t.txt files.

Nov 28, 2011

ubuntu 11.10 plus plasma widget

I recently install the ubuntu 11.10. I spent some time to get used to the unity interface.
But the unity shell is lack of widgets and therefore I decided to install the plasma-desktop to my ubuntu. :P


1. install the package by the following command:
   apt-get install plasma-desktop plasma-scriptengine-python
2. create launcher to start the plasma desktop:
   type gnome-desktop-item-edit ~/Desktop --create-new
   and it will popup a dialog box.
   select "application" in the type field,
   filled "plasma-desktop" or whatever u like in the name field,
   filled "plasma-desktop" in the command field,
   and press ok.
   P.S u can also create a launcher to stop the plasma by filled the command field with killall plasma-desktop.
3. Let plasma looks better in unity
   a. System Settings > Application Appearance > Widget Style > GTK+
   b. System Settings > Workspace Appearance > Desktop theme > Get new theme
   c. Search for ‘Ambiance’
   d. install it and use it.
   e. remove the bottom panel if u don't like it.
4. Use the nautilus as default folder manager
   control center(system setting) > file associations > inode > directory [ then add: "nautilus --no-desktop" ]
   or you can just install dolphin if u don't like the nautilus.

That's it enjoy!!

reference website:
http://www.omgubuntu.co.uk/2011/05/how-to-run-kde-plasma-widgets-in-ubuntu-unity/
https://bbs.archlinux.org/viewtopic.php?id=48046

Nov 12, 2011

setting linux as a gateway

Introduction:
Since my school project need to set up an ethernet environment. I need to create an internal network under virtualbox. The first step is to setup the gateway inside a virtualbox. After google for a while, I finally setting up my linux as a gateway.
Environment :
linux distribution: alpine linux 2.3
kernel version:    3.0
virtualbox network adapter setting:
     1. host-only network=> eth0 for internal network.
     2. bridged network => eth1 for internet.
the connection state is like the following figure:
<figure>
<<internet>>----------<<alpine linux>>------------<<internal>>
            eth1 pppoe                 eth0 NAT

P.S
The reason why I use alpine linux instead of other distribution is that it is tiny but contains the utilities that to set up my environment.
alpine linux download link:
http://alpinelinux.org/
alpine linux installation guide:
http://wiki.alpinelinux.org/wiki/Installation

Content:
I'll write down all the steps that I configure the internet.
include:
1. package requirement
2. configure the network interface
3. setting up the iptables
4. enable packet forwarding
 1.package requirement:

rp-pppoe => pppoe client side program
iptables => firewall
ppp  => ppp deamon
that's all. 

2.configure the network interface
   2.1. the internal network:
      configure the /etc/network/interface
      add the following line to the file.
auto eth0
iface eth0 inet static
address 192.168.56.254
netmask 255.255.255.0
network 192.168.56.0
broadcast 192.168.6.255
      the address, netmask, network and broadcast can be changed according to you network setting. 

   2.2.pppoe configuration:
      type 
      pppoe-setting => to start pppoe configuration. 
      After setting up type 
      pppoe-connect => connect to the internet via pppoe. 
      You can check the result by typing:
      ifconfig | less

3.setting up the iptables:
   type the following command to set the iptables rules:      
   iptables -A FORWARD -o eth1 -i eth0 -s 192.168.56.0/24 -m conntrack --ctstate NEW -j ACCEPT
   iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 
   iptables -A POSTROUTING -t nat -j MASQUERADE

4.enable packet forwarding:
    type
    echo 1 > /proc/sys/net/ipv4/ip_forward
    type
    cat /proc/sys/net/ipv4/ip_forward => check the result.

reference website:
http://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management#Packages_and_Repositories
http://www.linuxfromscratch.org/blfs/view/6.2.0/connect/other.html
http://tldp.org/HOWTO/DSL-HOWTO/configure.html
http://www.brennan.id.au/05-Broadband_Connectivity.html
https://help.ubuntu.com/community/Internet/ConnectionSharing

Oct 31, 2011

shell code 6(reduced the shellcode size)

The size of shellcode is very important. Therefore I list some of the tricks that can reduce the shellcode size and moreover rewirte our shellcode to reduce the size.

1.
Instead of using movl $constant , %register, use xor, mul and lea instead. The instruction of moving constant to register cost five bytes, but xor, mul and lea only cost 1 to 3 bytes. This can reduce many size of the shellcode.

The following is a quick example for the exit system call.
This is the original one that I write in the previous articles.
int main() {
  __asm__("movw $1, %eax;\
           movw $0, %ebx;\
           int $0x80;");
  return 0;
}
The size of each instruction is
mov $1, %eax      => 5 bytes.
mov $0, %ebx      => 5 bytes.
int $0x80         => 2 bytes.
------------------------------------
total bytes          12 bytes.

However if rewrite the shellcode into the following code:
int main() {
  __asm__("xorl %ebx, %ebx;\
           leal 0x1(%ebx), %eax;\
           int $0x80;");
  return 0;
}
The size of the shellcode become:
xorl %ebx, %ebx      => 2 bytes
leal 0x1(%ebx), %eax => 3 bytes
int $0x80            => 2 bytes
 --------------------------------------------
total size              7 bytes

yes, reduce 5 bytes of the shellcode. :D
another example of reducing the shellcode:
int main(){
        __asm__("jmp 0x20;\                 #2bytes
                 popl %esi;\                #1bytes
                 movl $4,%eax;\             #5bytes
                 movl $1,%ebx;\             #5bytes
                 movl $0x7,%edx;\           #5bytes
                 movl %esi,%ecx;\           #2bytes
                 int  $0x80;\               #2bytes
                 movl $1,%eax;\             #5bytes
                 movl $0,%ebx;\             #5bytes
                 int  $0x80;\               #2bytes
                 call -0x37;\               #5bytes
                 .string "Run Han"\
                 ");
        return 0;
}
This code is the write system call that I wrote in the previous article.
The code size of this shellcode is 46 bytes long.
rewrite the shellcode
__asm__("jmp 0x20;\                 #2bytes
                 popl %ecx;\                #1bytes
                 xorl %ebx, %ebx;\          #2bytes
                 mul %ebx;\                 #2bytes
                 leal 0x4(%eax),%eax;\      #3bytes
                 leal 0x7(%edx),%edx;\      #3bytes
                 int  $0x80;\               #2bytes
                 xorl %ebx, %ebx;\          #2bytes
                 leal 0x1(%ebx), %eax;\     #3bytes
                 int  $0x80;                #2bytes
                 call -0x37;\               #5bytes
                 .string "Run Han"\       #7bytes
                 ");
The code size is reduce to 34 bytes long.
P.S the mul instruction will save the result to %eax and %edx, therefore the %eax and %edx is now being set to zero. 
2. 
The push trick and relative jmp/call trick both can get the address of the data, but sometimes using the push trick in the right condition can reduce some bytes of the shellcode.
consider the following example in shell code 3:

int main(){
        /* relative jmp/call trick */
        __asm__("jmp 2f;\n\
                 1:;\n\
                 pop %esi;\n\
                 movl %esi, %ebx;\n\
                 movl $0, %ecx;\n\
                 movl $162, %eax;\n\
                 int  $0x80;\n\
                 movl $1,%eax;\n\
                 movl $0,%ebx;\n\
                 int  $0x80;\n\
                 2:;\n\
                 call 1b;\n\
                 .long 0x00000002,0x0;\n\
                 ");
        return 0;
} 
The above code is 42 bytes.
 
int main(){
        /* push trick */
        __asm__("push $0;\n\
                 push $2;\n\
                 movl %esp, %ebx;\n\
                 movl $0, %ecx;\n\
                 movl $162, %eax;\n\
                 int  $0x80;\n\
                 movl $1,%eax;\n\
                 movl $0,%ebx;\n\
                 int  $0x80;\n\               
                 ");
        return 0;
} 
The code size is 30 bytes.
By using the push trick, we reduced 12 bytes of the shellcode. Nice!!!

3.
The 0x66 prefix or 16bit/8bit mov instruction.
If the constant value is smaller than 0xffff using the 0x66 prefix or movw instruction in gnu assember. In this way, it can reduce one more byte of the shellcode.
If the constant value is smaller than 0xff using the movb instruction  since it only cost two bytes.
Rewrite the previous example:
int main(){
        /* push trick */
        __asm__("push $0;\n\
                 push $2;\n\
                 movl %esp, %ebx;\n\
                 xorl %ecx, %ecx;\n\
                 mov  $162, %al;\n\
                 int  $0x80;\n\
                 xorl %ebx, %ebx;\n\
                 leal 0x1(%ebx), %eax;\n\
                 int  $0x80;\n\               
                 ");
        return 0;
}
The size of the above code is reduce to 19 bytes.
Reduce 11 bytes of the code.
Now the wait system call and exit system call only cost 19 bytes instead of 42 bytes.

These tricks is very useful in some conditions, enjoy. :D

Oct 14, 2011

Dennis Ritchie R.I.P

#include <stdio.h>

int main(void){
         printf("Rest in piece Dennis Ritchie, father of the C language, great programmer and a true hacker. You changed the whole world.\n");
         return 0;
}

Oct 8, 2011

SimpleOS source code

I finally upload my OS source code to the github. The following is the link:
https://github.com/mike820324/SimpleOS

Recently I'm very busy because the school work. When my school work is finished, I will post some article about the source code, from the booting process to the protected mode in detailed. :P

Aug 13, 2011

Simple OS - note

While I was working on my simple operating system project. I found something interesting.
Almost all the x86 system boot up in 16-bit real mode. And the way to enable the protected mode is quite easy.
As osdev wiki suggest, using the following instruction can take us from real mode to protected mode.
....
mov  eax, cr0   ; switch to pmode by
or al,1         ; set pmode bit
mov  cr0, eax
.....
 
But there are one thing that bother me a lot, since our code is still in the real mode, 
how can we use the 32-bit register and instructions.
 
After google for a while I found a very helpful website that completely solved my question.
answer in stackoverflow 
answer in nasm forum 
  
The answer is that
When intel introduced 32-bit code - they used the same opcodes! 
When using 32bit register in 16 bit real mode, assembler will place a prefix in front of the instruction. (0x66 according to the nasm forum) This tell the cpu that I'm using 32-bit register
in 16-bits real mode.

I take some picture to verified the result.
My environment is ubuntu 10.10 and gcc 4.4.5
I' using qemu and gdb to verified the result.

 
  
As you can see, there are 0x66 prefix in front of the mov eax, 0 instruction.

Labels