Archive

Archive for September, 2009

Full disclosure… or not?

September 26th, 2009 2 comments

One of the biggest problems I face sometimes is what should I do when I find a bug. I recently found a bug at the linux kernel version 2.6.30, which was fixed at 2.6.31, but I only told it to a friend of mine. Posting the description to a mailing list or at my blog would mean that everybody could write an exploit and use it to hack into systems. I could also write a patch which could be merged at the next release. For the moment I chose not to do anything until the next kernel release and if it wasn’t fixed I would then decide what should I do.
I face the same problem when I write security related programs. For example, a rootkit that can be used for malicious purposes can also be used to demonstrate bugs at the design of an operating system. Should a program like this be released?
I have created the following two polls. I believe that the results are going to be very interesting!

Categories: Security Tags:

Inline assembly the gcc way

September 15th, 2009 3 comments

This is the second time I write a post about inline assembly. The last one was at my old blog which I had to remove. However, since that was the most viewed article I think I should write about this again. Although this is just a small introduction, you must know C and assembly in order to continue. For the moment I will only describe x86 assembly, however the differences for other architectures are minimal. I must also point you to the GCC Inline Assembly HOWTO. I wrote the first post before reading it (well, the post was ready but before publishing it I googled a little bit and found it) and I think it is equally useful.

We are going to start with a little introduction to the AT&T syntax for the assembly for all of you who are familiar only with Intel syntax. Here are some basic rules:

  • Registers: All register names begin with the character %. So, if we want to use the eax register, then we will use the name %eax.
  • Immediate operands: The immediate operands begin with the character $. For example, if we want to use the value 0xdeadbeef as an immediate operand, then we will use $0xdeadbeef.
  • Indirect memory references: Indirect memory references are done using ( ). The byte pointed by register %esi is (%esi). If you want to use an offset, you put it in front of the (register). Warning! Since it is not an immediate operand, you don’t have to use the $. For example, you should use 0x4(%esi) and not $0x4(%esi).
  • Ordering of the operands: The ordering is:
    instruction source, destination
    This is the reverse of the intel syntax where the destination comes first.
  • Size of operand: All instructions taking operands that can have variable sizes must be suffixed with the appropriate letter:
    • b – Byte (1 byte)
    • w – Word (2 bytes)
    • l – Long (4 bytes)
    • q – Quad word (8 bytes) – Only when you use 64 bit programs.
  • Immediate long jumps and calls use the form
    ljmp/lcall $section, $offset
    instead of
    jmp/call far section:offset

Here are some examples in intel and at&t syntax.

Intel syntax:

This gets translated to:

If you want to see more examples, you can write your own code and disassemble it using the objdump command. By using the -d option you can disassemble any file you want. The default syntax is at&t but if you want to switch to intel you can add -M intel to the command line.

We can now continue to putting inline assembly to our programs. In order to insert assembly code we must use the “asm” construct.

This will execute a simple nop instruction. In case asm conflicts with something else in your program you can also use __asm__. Apart from this there is also a more advanced format.

The assembly template is your actual assembly code with some special operands that will be replaced by registers or memory locations. This code will be send directly to the assembler, so if you want to run more than one command you must use one of the following constructs:

OR

OR

The last one uses ; which is the line separator at most architectures. Since we are going to use only x86 we are free to use it, however, at other architectures, like H8/300, ; is the comment character. You can check the gas info page for more information about the line separator character.

The output and input operands are two lists the have the form

"constraint"(variable), "constraint"(variable), ...

At the output operands a constraint denotes what will be placed at variable after the execution of the assembly code and at the input operands a constraint denotes where a variable will be placed. The various constraints for the x86 architecture are:

  • r: any register, one will be chosen by the compiler
  • a: eax register
  • b: ebx register
  • c: ecx register
  • d: edx register
  • S: esi register
  • D: edi register
  • A: eax and edx combined as a 64-bit integer
  • f: floating point register
  • t: first floating point register
  • u: second floating point register
  • m: memory operand
  • 0-9: matching operand

The memory operand will not use a register, it will only pass the location of variable in memory. Furthermore, the matching operand is used when a register is used both as input and as output, e.g. by specifying 0 as an input operand, the first output register will be used for input. You must prefix the output constraints with the = character. If you use the r constraint more than once, the same register may be assigned. If you want to choose a different register, you should use the & character, i.e. the constraint &r.

Finally, the list of clobbered registers is a list of all registers modified by your program. These registers must have the format %eax, %ebx etc.

If your code must execute exact;y at the place you put it, you must put the volatile keyword after asm or __volatile__ after __asm__. Otherwise, the compiler may change its position if optimization takes place.

I will present some simple examples.

At the first example I will read the timestamp counter. This is done using the rdtsc command which returns the result at eax and edx.

The generated code will be:

-16(%ebp) and -12(%ebp) are the two words that hold the unsigned long long tsc that will get the timestamp counter.

The second example will read and print some cpuid information.

I will only present the second part of the program which prints the processor brand.

Location -32(%ebp) stores the op variable. At the beginning it is assigned the value 0x80000002. I will not comment the code generated for the loop, it is pretty simple. After the .L3 label the inline assembly begins. At the beginning, the op value is moved to the register %eax since it is in the input operands list with the constraint a. The cpuid instruction is then executed since it is in the assembly template. Finally, all registers at the output operands list are saved to the appropriate location, i.e. -28(%ebp) for %eax, -24(%ebp) for %ebx, -20(%ebp) for %ecx and -16(%ebp) for %edx.

You can find more information by writing your own programs and disassembling them using the objdump utility.

If you like this post I will continue with something more advanced.

Categories: Assembly, Programming Tags:

Debugging the linux kernel using kgdb and VirtualBox

September 6th, 2009 8 comments

Kgdb is a source level debugger for the linux kernel. It requires two machines, one running a kernel compiled with kgdb enabled and the second one running gdb. It can be found at sourceforge and a light version has been merged into the 2.6.26 kernel. There is an article at kerneltrap which contains all the appropriate information about this light version and it’s differences from the full one. I am going to describe how you can debug a linux kernel running under VirtualBox using the kgdb-light debugger.

First of all you must define a serial port. Go to the settings of your virtual machine, then at the “Serial Ports” and enable “Port 1”. Use port number COM1, port mode ‘Host Pipe’, check ‘Create Pipe’ and enter a path, e.g. /home/fotisl/virtualbox/myvm/serial1. You can use another port number, e.g. COM2, but then you’ll have to change the device below to ttyS1, ttyS2 for COM3 etc. Furthermore, you can create the pipe yourself and not automatically using:

At your virtual machine you must have a kernel compiled with the option CONFIG_KGDB. You can find this under the “Kernel debugging” menu. I also advise you to enable the CONFIG_DEBUG_INFO to insert debug symbols.

At the host machine you only need to install socat and of course gdb. Socat is a multipurpose relay which can be found here. You should also transfer the uncompressed image of the kernel running at the vm. It can be found at the directory where you compiled the kernel and it’s name will be vmlinux.

You are now ready to start. At the host machine run:

You must note the PTY, in this case /dev/pts/4. Now fire gdb and load vmlinux. Then set the remote baud to 115200 and attach to the serial port.

Now switch to the virtual machine. You must first set the serial port that kgdb will use.

You’re ready to start debugging! When you want to break use the Alt-SysRq-G key combination or use

If you want to start the debugging when the kernel starts loading, append

to the command line parameters of the kernel. You must use this order! First you must register the I/O driver and then kgdb will be able to wait.

You can now explore the linux kernel! Warning, messing with various structures and executing code that you shouldn’t can cause kernel panics and mess up your virtual machine! But you already know that, that’s why you use virtualbox!

Categories: Linux, Linux Kernel, Programming Tags:
SEO Powered by Platinum SEO from Techblissonline

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close