in the name of zero

November 8, 2008

let’s learn powerpc linux!

i’m actually using gcc4 and noticed that there are minor deviations
from the usual prolog/epilog functions since gcc3 when doing intel. i
have to read up on this.

so let’s try to follow a simple “hello world” program to see how gcc makes ppc
programs. it’s compiled with no optimizations.

int procedure1(const char *string)
{
        printf(string);
        return 0;
}
	
int main(int argc, char *argv[])
{
        return procedure1(\"hello world\n\");
}

the V4 stack frame.

	SP---->	+---------------------------------------+
		| back chain to caller			| 0
		+---------------------------------------+
		| saved LR				| 4
		+---------------------------------------+
		| Parameter save area (P)		| 8
		+---------------------------------------+
		| Alloca space (A)			| 8+P
		+---------------------------------------+
		| Local variable space (L)		| 8+P+A
		+---------------------------------------+
		| saved CR (C)				| 8+P+A+L
		+---------------------------------------+
		| Save area for GP registers (G)	| 8+P+A+L+C
		+---------------------------------------+
		| Save area for FP registers (F)	| 8+P+A+L+C+G
		+---------------------------------------+
	old SP->| back chain to caller's caller		|
		+---------------------------------------+

the V4 Registers

r0 volatile, may be used by function linkage
r1 stack pointer
r2 reserved for system
r3 .. r4 volatile, pass 1st - 2nd int args, return 1st - 2nd ints
r5 .. r10 volatile, pass 3rd - 8th int args
r11 .. r12 volatile, may be used by function linkage
r13 small data area pointer
r14 .. r31 saved
f0 volatile
f1 volatile, pass 1st float arg, return 1st float
f2 .. f8 volatile, pass 2nd - 8th float args
f9 .. f13 volatile
f14 .. f30 saved
f31 saved, static chain if needed.
lr volatile, return address
ctr volatile
xer volatile
fpscr volatile*
cr0 volatile
cr1 volatile**
cr2 .. cr4 saved
cr5 .. cr7 volatile

* The VE, OE, UE, ZE, XE, NI, and RN (rounding mode) bits of the FPSCR may be
changed only by a called function such as fpsetround that has the documented
effect of changing them, the rest of the FPSCR is volatile.

** Bit 6 of the CR (CR1 floating point invalid exception bit) is set to 1 if a
variable argument function is passed floating point arguments in registers.

the PPC architecture does not have a push/pop instruction that implicitly
operates on the stack. as such, stack management could be a little more “hands
on” on PPC in comparison to intel. the stack frame convention above is defined
to support parameter passing, reserved registers (nonvolatile) preservation and
local variables. each function which either calls another function or modifies
saved register must create a stack frame from memory set aside for use as a
stack defined by the r1 register (r1 = sp).

the stwu instruction assures that stack frame allocation is atomic. stack
space is allocated and the sp (r1) is updated in just one instruction.

parameter passing. ppc passes function parameters thru registers rather than
pushing them all in the stack.

<procedure1>
stwu    r1,-32(r1)  ; save former and allocate a new stack frame
mflr    r0          ; return addr of procedure1()
stw     r31,28(r1)  ; save r31
stw     r0,36(r1)   ; save r0
mr      r31,r1      ; mirror sp
stw     r3,8(r31)   ; save char * to stack
lwz     r3,8(r31)   ; argument to printf
bl      10010a00

li      r0,0        ; r0 = 0
mr      r3,r0       ; r3 = 0 = return value
lwz     r11,0(r1)   ; access back chain
lwz     r0,4(r11)   ; access return address
mtlr    r0          ; update link register with return addr of procedure1()
lwz     r31,-4(r11) ; restore r31
mr      r1,r11      ; restore caller’s stack
blr                 ; return to caller
	
<main>
stwu    r1,-32(r1)      ; save former frame and allocate a new stack frame
mflr    r0              ; return address of main()
stw     r31,28(r1)      ; save r31
stw     r0,36(r1)       ; save link register
mr      r31,r1          ; mirror sp
stw     r3,8(r31)       ; save r3
stw     r4,12(r31)      ; save r4
lis     r9,4096         ; lower 16 bits of string addr
addi    r3,r9,2176      ; higher 16 bits of string addr
bl      10000434
 ; procedure1(char *)
mr      r0,r3           ; r0 = return val of procedure1()
mr      r3,r0           ; r3 = 0 (retval)
lwz     r11,0(r1)       ; access back chain
lwz     r0,4(r11)       ; access return address
mtlr    r0              ; update link register
lwz     r31,-4(r11)     ; restore r31
mr      r1,r11          ; restore stack frame
blr                     ; leave main()

next time, we’ll delve more deeper and see how to access system calls directly
and how these system calls are implemented.

July 12, 2008

grainne2

i know how how it feels like to have a burning hole in your heart that can only be
filled with a loved one. but sometimes, we have no choice but to accept our
fate. - kenshin himura

it’s “grainne2″!! i decided to make it available here while i’m still waiting for the mods at crackmes.de to put it up. i’ll post a solution after a week or two..

update: crackmes.de page for “grainne2″ here. enjoy you guys..

dedicated to Grainne C. Yap - the girl who broke my heart.

June 14, 2008

on my own and moving on

i’ve been puting off a lot of things lately. at the top of my list is to give some just attention to this little web space of mine. its not because i don’t have time anymore. its just that, i felt the need to explore some de-stressing activities other than writing my thoughts and rants down. i always found writing rather emotionally helpful, but during those carefree college days, i rarely
did anything to the point of exhaustion.

but im bringing my hiatus onto a peaceful end. good day! gentoo powerpc land!

September 29, 2007

life

sucks.

oh! what a cliche…

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.

May 27, 2007

the grainne crackme

before anything else, lagalopex and devloop solved the crackme. special mention to lagalopex for identifying the cause of the bug that causes the segfault. the obvious fix would be to gurantee zero flag state before doing a jz/jnz but i simply changed the jz to a jnz because it was the most convenient thing to do.

1) the crackme is an elf from scratch binary that contains a few instructions inside the elf header itself.

2) the entire file is mapped “read/execute” to a text segment (thru an Elf32_Phdr) with a data segment mapped “read/write” in the middle (thru another Elf32_Phdr).

3) the crackme uses an array of function pointers to do flow control. the vptr table thingy i learned from studying the simple c++ binaries i made a month ago sort of inspired me implement a simplistic version. the address of the array is acquired by implementing a known/common trick used in many shellcodes. jump to an address, then put the address of the EIP on the stack plus transfer execution flow by doing a “call”, then “pop” to get the desired memory address (ret address) from the stack.

e.g.

_start:		jmp known_add
real_start:	pop edx		; this will pop the ret val on stack which is the address of function1
		...
		...
	
known_add:	call real_start
		dd function1	; start of function pointers...
		dd function2
		...
		...
	
function1:	; function1 block of intructions...

the crackme’s vptr table (which is really just an array of function pointers) start immediately after the elf head. why is this so? this is because i want the “call” instruction to be placed inside the elf header (occupying the last few bytes). so when anyone will do a readelf -h to try to get more info, they’ll notice that the last three fields are whacked.

$ readelf -h grainne
	...
  Size of section headers:           59392 (bytes)
  Number of section headers:         65498
  Section header string table index: 65535
readelf: Error: Out of memory allocating 0xe7dd9000 bytes for section headers

this also has the added benefit that function calls aren’t simply followed by jumping to the address to “call” inside an interactive disassembler.

some people in the crowd would try to fix (or nullify) related key fields in the elf header in the hopes at least getting gdb to work so if ever they did, they’d actually be erasing some instructions found in the elf header, e.g. the call instruction to determine the address of the function pointer array.

and because of how the elf head is contructed we could now expect scenarios like the ones below:

$ file grainne
grainne: ELF 32-bit LSB executable, Intel 80386, version 1, statically linked, corrupted section header size
	
$ objdump -d grainne
objdump: grainne: File format not recognized
	
$ objdump -x grainne
objdump: grainne: File format not recognized
	
$ gdb grainne
“/home/misha/grainne/grainne”: not in executable format: File format not recognized
	
$ ald grainne
Assembly Language Debugger 0.1.7
Copyright (C) 2000-2004 Patrick Alken
	
Segmentation fault

4) the crackme calls functions by first associating a signal handler to the SIGTRAP signal and implicitly calling the handler by using the 0xCC byte.

5) there are some garbage instructions like:

	push 0xbadc0de
	ret
which is really just dead code in whatever way you see it. (unless someone actually tries to get over jmps)

6) lastly, and this is the most predictably easy part is that the crackme encodes user input to compare it to a hard coded string. the result determines the crack state.

i guess that’s all there is to it.

in other news, summer’s coming to a close and i never got to write an entry “summer love lessons 07″. all in all, i think this is a rather relaxing summer. for one, i don’t have to worry about school/enrollments anymore come june. moreover, i made friends with a (pretty/cute) korean girl named “carol” but she’s in malaysia right now for studies. she called the other night and i must say that her voice is sweet and charming. we talked for a few minutes… it’s kinda old fashioned, but we agreed to be penpals. i’m excited about writing and sending her letters already!

well then, i’ll close this blog entry at that.

May 17, 2007

grainne

dedicated to the girl who showed me that university can be fun if you’re inlove.

it’s written in pure assembler. i’ll post snippets and a few explanations as soon as a solution will be posted. oh, and for what it’s worth, my testbed for it is linux 2.6.12-gentoo-sources.

errata and download link here happy reversing.

[update]
lagalopex reported that the segfault is caused by two “jz” instructions somewhere. i wonder why the zero flag on my machine (that is linux 2.612) starts out ON. anyway, i’ve changed those two instructions and uploaded an updated (hopefully error free) version here.

April 26, 2007

0xf001’s 0xf001m3

hack the password!

features: a anti-libbfd, anti-disassembling, anti-debugging, and a bit of obfuscation ;)

have a lot of fun … ;}

0xf001

Difficulty: 5 - Professional problem to solve
Platform: Unix/linux etc.
Language: Assembler

get it here

as you’ll find out soon after starting,

1) the crackme is filled with anti-disassembly constructs.
2) along the way, there are lots and lots (and lots) or jump via ret/double rets. it’s simply just a matter of fixing/telling the disassembler the correct offset where to start disassembly (IDA in my case)
3) there is a short encrpytion thingy goin on
4) the crackme hides the details of setting up the parameters for a system call among the many jump via ret/double rets
5) patches an int 0x80 before calling it. patches it back after calling it.

example of jump via “ret” in the crackme

0x8048080		call loc_8048086	; put 0x08048085 to esp
0x8048085		db 0E9h			; garbage
0x8048086		pop edx			; edx = 0x08048085
0x8048087		add edx, 0Bh		; edx = 0x08048090
0x804808D		push edx		; on stack
0x804808E		retn			; jump to 0x08048090

“double ret”

0x080480E0		add edx, 0xe		; fix 2nd jump address
0x080480E6		push edx		; put on stack
0x080480E7		push 0x80480cc		; 1st jump address
0x080480EC		retn			; return once
0x080480CC		retn 			; return twice

we can basically grasp the pattern immediately after a few tries…. going further we reach a “sign of life” of some sort.. a lodsb instruction.

0x08048130		mov al, [+0x8048c90]
0x08048135		lodsb			; esi initially at  0x08048196

which will put the first byte at 0x08048196 (0xCC) to al, then increment esi. a few blocks further…

0x08048154		xor al, 0x58		; byte morph ...

…another series of ret/double rets… then we have

0x08048174		stosb			; initially at 0x08048196

eventually, a “loop”

0x08048193		loop +0xa0 (0x8048235)	; 0xa80 times

tell tale signs of decryption don’t you agree? so if we do the math, 0x08048196 + 0xa80 = 0x08048C16. what i want to achieve as of the moment is a copy of the decrpted block so that i can still follow ald’s debugging session in ida. we can take a memory dump of the crackme. i on the other hand chose to make a helper program[1] that will decrypt the encrypted block.

another set of jump via ret/double ret series…

we basically continue till we reach a shl eax, 1 instruction.

08048783                      D1E0                 shl eax, 1  

from the current value of eax = 0xd, the shift left by one bit will make eax = 0x1a (26 decimal) which happens to be the syscall number for sys_ptrace()

series of jump via ret again…

former value of ecx = 0x10 .. via shl cl, 0x3 becomes ecx = 0x80

0804893C                      C0E103               shl cl, 0x3 

further along the way, this instruction patches the byte pointed to by edx (0x08048A4E) with cl = 0x80 (which by the way, is also the linux interrupt vector)

880A                 mov byte [edx], cl 

still following the trail… we now reached the instruction at address 0x080489C4. which is a jz 0x08048653. if we follow this jump (in the disassembler), we’ll reach the dead end which is where the crackme will try returning to 0xf001. we don’t want our debugging session disrupted, so let’s skip that instruction. eventually, (after yet another series of jump via rets) we reach an int 0x80 instruction at 0x08048A4D. remember the mov byte [edx], cl instruction a while ago? the crackme patches this location at runtime in order for a ptrace() system call to resolve.

we can easily defeat this (ald in my case) by giving eax = 0 value.

going further we eventually encounter

08048AA7                      BA4E8A0408           mov edx, 0x8048a4e ; this will later be overwitten then restored...

…. more jump via rets …

08048AD7                      880A                 mov byte [edx], cl

so the crackme patches the int 0x80 byte (to cover its tracks). then after a helluva lot of nuisances….

0x08048826	or al, al	; the crackme tries to toggle the zero flag

and further down the listing…

0x08048853                      0F85FAFDFFFF         jne near +0xfffffdfa (0x8048653)

wait a minute! we’ve already seen this memory address once right? it’s the path leading to 0xf001! so let’s skip that instruction and we’ll safely reach the next set of surprises.

things get interesting starting at 0x080481B5. we encounter more and more of those jump via ret thingies along the way but at least now we now the pattern on how they work…

we encounter another int 0x80 patch so we know something’s gonna turn up soon. the details on how parameters are being setup is hidden among tons of repetitive jump via ret/double calls. don’t forget that the crackme also patches int 0x80 again after every call. we can also determine that address 0x080485bc is the address responsible for the flow of the crackme after every int 0x80 payload. i opted to simply check the registers (parameters) before every int 0x80 call.

ecx = 0x080481D5 (oxfoo1m3 started ;])
ecx = 0x0804820F (3nt4 p455w0rD:)

we now enter the fourth int 0x80 installment (0x0804835C). this time, instead of entering the usual routine (setup int 0x80) the crackme does an int 0x80 directly. checking the registers, we have:


eax = 0x00000003 ebx = 0x00000000 ecx = 0x08048223 edx = 0x0000000B

sys_read 0x0b characters from stdin and save to buffer at 0x08048223. i guess that brings us to the fifth phase… roughly like the one below.

at 0x080483e2, we see the mov esi, 0x08048223 instruction… and another interesting instruction at 0x08048412 (mov edi, 0x8048223).

08048472                      AC                   lodsb  ; load byte (esi) to al
0804849E                      30D0                 xor al, dl ; dl is strlen(input)
080484CB                      FEC2                 inc dl
08048582                      3A01                 cmp al, byte [ecx]    ; aha!

by virtue of common sense.. i made a keygen[2] immediately to test things out.

works like a charm.


~/oxfoo1m3 $ ./cracker
password is : fucktheduck
	
~/oxfoo1m3 $ ./oxfoo1m3
oxfoo1m3 started ;]
3nt4 p455w0rD:
fucktheduck
u made it!

thanks to 0xf001 for this wonderful crackme.

references:
[1] decrypt_foolme.c
[2] cracker.c

April 5, 2007

virtuals

so i’m back with more of the shit that is C++ learning. i’ve gotten the hang of typing “cout” now instead of “printf” but more about this some other time. recently, i’m learning about virtual functions and i have this as an example:

class animal {
        public:
                void normal() { }
                virtual void normvirtual() { }
                virtual void purevirtual() = 0;
};
	
class sheep : public animal {
        public:
                void normvirtual() {
                        cout<<"sheep from normvirtual"<<endl;
                }    
	
                void purevirtual() {
                        cout<<"sheep from purevirtual"<<endl;
                }
};

again, using IDA and objdump …

 sheep   judy;
	
 8048803:       8d 45 e8                lea    eax,[ebp-24]
 8048806:       50                      push   eax
 8048807:       e8 8a 00 00 00          call   8048896 <sheep::sheep()>

nothing much happening here. the usual thing. a *this pointer being passed to a default constructor as a hidden argument.

08048896 <sheep::sheep()>:
 8048896:       55                      push   ebp		; save current stack frame
 8048897:       89 e5                   mov    ebp,esp		; new stack frame
 8048899:       83 ec 08                sub    esp,0x8		; space
 804889c:       83 ec 0c                sub    esp,0xc		; space
 804889f:       ff 75 08                push   DWORD PTR [ebp+8]		; our *this pointer
 80488a2:       e8 4d 00 00 00          call   80488f4 <animal::animal()>	; call animal constructor
 80488a7:       83 c4 10                add    esp,0x10				; cleanup
 80488aa:       8b 45 08                mov    eax,DWORD PTR [ebp+8]		; dereference
 80488ad:       c7 00 80 8a 04 08       mov    DWORD PTR [eax],0x8048a80	; see below...
 80488b3:       c9                      leave  			; epilog
 80488b4:       c3                      ret    			; return to callee
 80488b5:       90                      nop    			; byte pad (no operation)

so what does mov DWORD PTR [eax],0x8048a80 do? following the memory address in ida gives me an array of sheep class functions. objdump tells me that this block is called a “vtable” for my sheep class. 0x8048a80 is prolly what they call the “VPTR” pointer.

and then i called the get_kind() function.

 get_kind(judy);
	
 8048812:       8d 45 e8                lea    eax,[ebp-24]
 8048815:       50                      push   eax
 8048816:       e8 9b 00 00 00          call   80488b6 <get_kind(animal&)>

i learned from prior readings about “upcasting” and how a derived class object can be assigned to base class object. and this is how i interpreted things…

inline void get_kind(animal &a)
{
	a.normal();
	a.normvirtual();
	a.purevirtual();
}   
	
080488b6 <get_kind(animal&)>:
 80488b6:       55                      push   ebp
 80488b7:       89 e5                   mov    ebp,esp			; prolog
 80488b9:       83 ec 08                sub    esp,0x8
 80488bc:       83 ec 0c                sub    esp,0xc			; spaces
 80488bf:       ff 75 08                push   DWORD PTR [ebp+8]		; object as hidden argument
 80488c2:       e8 3b 00 00 00          call   8048902 <animal::normal()> 	; call the animal::normal() method
 80488c7:       83 c4 10                add    esp,0x10			; cleanup
 80488ca:       83 ec 0c                sub    esp,0xc			; space
	
 80488cd:       8b 45 08                mov    eax,DWORD PTR [ebp+8]	; *this pointer (VPTR)
 80488d0:       8b 00                   mov    eax,DWORD PTR [eax]	; dereference
 80488d2:       ff 75 08                push   DWORD PTR [ebp+8]	; pass object again as hidden argument
 80488d5:       8b 00                   mov    eax,DWORD PTR [eax]	; derefence again
 80488d7:       ff d0                   call   eax			; call the first virtual function
 80488d9:       83 c4 10                add    esp,0x10			; cleanup
 80488dc:       83 ec 0c                sub    esp,0xc			; space
	
 80488df:       8b 45 08                mov    eax,DWORD PTR [ebp+8]	; *this pointer (VPTR)
 80488e2:       8b 00                   mov    eax,DWORD PTR [eax]	; dereference
 80488e4:       83 c0 04                add    eax,0x4			; move to next function in array of funtions
 80488e7:       ff 75 08                push   DWORD PTR [ebp+8]	; pass object as hidden argument
 80488ea:       8b 00                   mov    eax,DWORD PTR [eax]	; dereference
 80488ec:       ff d0                   call   eax			; call second virtual function
	
 80488ee:       83 c4 10                add    esp,0x10			; cleanup
 80488f1:       c9                      leave  				; epilog
 80488f2:       c3                      ret    				; return to callee
 80488f3:       90                      nop  				; byte pad (no operation)

i wonder if i got the above things right? dynamic binding entails an additional overhead of locating and assigning the correct memory address for a particular function call to resolve. the whole thing is somehow similar to ELF PLT.GOT fixup (executable and linkable format procedure linkage table global offset table) except that addresses are always being referenced from the VPTR whenever a virtual call will be made.

also, there is a subtle difference between a normal virtual and a pure virtual function. from the looks of things, the pure virtual function takes up no space. in fact, i didn’t even see any single declartion of animal::purevirtual() anywhere on the dissassembly.

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