in the name of zero

June 14, 2007

untitled…

i followed my heart… i’m soooooooooooo happy right now… and will be for at least 4 years!

god bless her.

June 10, 2007

break

Filed under: easter eggs

i’m going through a lot right now… be posting when things settle down … in the meantime, please point your browsers to crackmes dot de

semper fi.

June 4, 2007

module_init() and the init_call mechanism of linux

Filed under: hermetic studies

today, i tried to implement an initcall mechanismbased on what i’ve learned from linux. it works somehow. most of the work is being done at subsystem.c

i defined 3 levels of initcall .initcall1.init , .initcall2.init and .initcall6.init which are simply just the section name counter parts of core_initcall(), postcore_initcall() and device_initcall().

on the trail of module_init

Filed under: hermetic studies

ok for everyone’s information, i fancy anything ELF to an almost (but not quite) fanatic degree. my motivation for the activity below came when i straced insmod to see what kind of activity it does and there i encountered a few syscalls i haven’t had any chance to use nor to read about.

# strace insmod binfmt_mp3.ko
 ...
 create_module(NULL, 0)                  = -1 ENOSYS (Function not implemented)
 ...
 init_module(0x804b060, 3094, "")        = 0
 ...

grepping for module in unistd.h sort of paid off:

$ grep -i module /usr/include/asm/unistd.h
#define __NR_create_module      127
#define __NR_init_module        128
#define __NR_delete_module      129
#define __NR_query_module       167

and just to confirm things …

$ file binfmt_mp3.ko
binfmt_mp3.ko: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
i decided i’d try following what happens to a module on module_init() as it’s the entry point of lkms.

linux/init.h
	
typedef int (*initcall_t)(void);
	
#define __define_initcall(level,fn) \
        static initcall_t __initcall_##fn __attribute_used__ \
        __attribute__((__section__(".initcall" level ".init"))) = fn
	
#define device_initcall(fn)             __define_initcall("6",fn)
	
#define __initcall(fn) device_initcall(fn)
	
#define module_init(x)	__initcall(x)

apparently, initcalls also have levels.

linux/init.h
	
#define core_initcall(fn)               __define_initcall("1",fn)
#define postcore_initcall(fn)           __define_initcall("2",fn)
#define arch_initcall(fn)               __define_initcall("3",fn)
#define subsys_initcall(fn)             __define_initcall("4",fn)
#define fs_initcall(fn)                 __define_initcall("5",fn)
#define device_initcall(fn)             __define_initcall("6",fn)
#define late_initcall(fn)               __define_initcall("7",fn)

and based on the macros’ above, a module_init(function) roughly creates a function pointer entry “__initcall_function” in a section called “.initcall6.init”. __attribute_used__ tells the compiler to generate code even if it appears like the function isn’t refenced.
i have this object file from drivers/block/floppy.o as reference:

$ objdump -t floppy.o | grep -i initcall
00000000 l    d  .initcall6.init        00000000 .initcall6.init
00000000 l     O .initcall6.init        00000004 __initcall_floppy_init

yeah, i couldn’t find any initcallx.init section for lkms though. so i suppose initcall is something that works only if your module is compiled in-kernel.

the kernel linker script dedicates a special block for the “.initcallX.init” sections. bounded by __initcall_start and __initcall_end respectvely.

/arch/i386/kernel/vmlinux.lds
	
__initcall_start = .;
.initcall.init : {
	*(.initcall1.init)
	*(.initcall2.init)
	*(.initcall3.init)
	*(.initcall4.init)
	*(.initcall5.init)
	*(.initcall6.init)
	*(.initcall7.init)
}
__initcall_end = .;

looking for references to those two variables led me to init/main.c where the kernel traverses the .initcall*.init function pointers calling each function till __initcall_end.

init/main.c
	
extern initcall_t __initcall_start[], __initcall_end[];
	
init/main.c::static void __init do_initcalls(void)
	
        initcall_t *call;
        int count = preempt_count();
	
        for (call = __initcall_start; call < __initcall_end; call++) {
                char *msg;
	
                if (initcall_debug) {
                        printk(KERN_DEBUG "Calling initcall 0x%p", *call);
                        print_fn_descriptor_symbol(": %s()", (unsigned long) *call);
                        printk("\n");
                }
	
                (*call)();
	
		...

the do_initcall() function itself is found in another init section “.init.text”

that’s all i know for the time being.

June 2, 2007

run mp3s anyone?

i posted an entry the other day about playing with binary formats and i’ve been reading linux/binfmt_script.c in my free time eversince. the logic is simple i think; linux kernel enters a loop calling a linked list of binary format loaders:

fs/exec.c::search_binary_handler()
	
    for (fmt = formats ; fmt ; fmt = fmt->next) {
                        int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
                        if (!fn)
                                continue;
                        if (!try_module_get(fmt->module))
                                continue;
                        read_unlock(&binfmt_lock);
                        retval = fn(bprm, regs);
			...

so binfmt_script.c adds script execution functionality to the linux kernel by registering a loader thru register_binfmt(&script_format). so we’d assume that when we call a script (text file), the kernel will eventually call binfmt_script.c::script_format() to take control. the function then takes care of checking for the sha bang line, parse the interpreter after found in the sha bang line including the arguments .. and then muck around the original linux_binprm struct so that the original executed file (script file in this case) now becomes the argument to the interpreter found in the sha bang line… finally, it restarts the entire exec procedure by calling search_binary_handler() again.

for practice, i decided to make mp3s runnable.

we obviously can’t do this…

$ ./kangta\ -\ propose.mp3
bash: ./kangta - propose.mp3: cannot execute binary file

now, in the spirit of binfmt_script.c, i took into consideration the intrepreter and the script. in my case, intrepreter happens to be /usr/bin/mplayer and consequently, the script is the mp3 file. i grepp’ed /usr/share/misc/file/magic for mp3 signatures and finally constructed binfmt_mp3.c

$ file kangta\ -\ propose.mp3
kangta - propose.mp3: MP3 file with ID3 version 2.3.0 tag
	
$ chmod +x kangta\ -\ propose.mp3 
	
$ ./kangta\ -\ propose.mp3
 ...
Starting playback...
A:  32.2 (32.1)  1.3% 33%

the next step would be to raise flexibility by adding a procfs entry to change the player on the fly. e.g. echo “/bin/mpg123″ > /proc/useless/binfmt_mp3 but that’s a learning project for some other time.

i’ve uploaded the files here if anyone’s curious.

the grainne crackme source

i’ve uploaded the source code to my grainne crackme here.

Get free blog up and running in minutes with Blogsome | Theme designs available here