- Prison Code Breaker Diary -

=> aka: Nhật Kí Code Tù

Categories

Today, we will learn a new widget control, GtkEntry, a text editor. It's a text box that users can input text inside.
Reference GtkEntry

I'm not gonna explain each properties and methods in details anymore. However, to practice directly is the better way of learning it since you've already familiar with Gtk+ programming.

Practice 1: A simple one, a label will show up everything you type in the entry box when clicking a button.



/*
* @author [JaPh]
* @date 30 August, 2009
* @file GtkEntry_01.c
* @site http://xjaphx.blogspot.com/
*/

#include <gtk/gtk.h>
#include <glib.h>
typedef struct _STORE {
GtkLabel *label;
GtkEntry *entry;
} STORE;

void
btn_get_clicked_event( GtkButton *btn_get, STORE *data )
{
gtk_label_set_text( data->label, gtk_entry_get_text(data->entry));
}

int
main( int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *label;
GtkWidget *entry;
GtkWidget *btn_get;
GtkWidget *vbox;
STORE *data;

gtk_init( &argc, &argv );

window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title( GTK_WINDOW(window), "[JaPh]Lesson 13: GtkEntry" );
gtk_window_set_default_size( GTK_WINDOW(window), 100, 100 );

label = gtk_label_new("Type anything to entry below: ");
btn_get = gtk_button_new_with_mnemonic("_Get");
entry = gtk_entry_new_with_max_length( 128 );

vbox = gtk_vbox_new( TRUE, 5 );

gtk_box_pack_start( GTK_BOX(vbox), label, TRUE, TRUE, 5);
gtk_box_pack_start( GTK_BOX(vbox), entry, TRUE, TRUE, 5);
gtk_box_pack_start( GTK_BOX(vbox), btn_get, TRUE, TRUE, 5);

data = (STORE *) g_malloc( sizeof (STORE) );
data->label = GTK_LABEL(label);
data->entry = GTK_ENTRY(entry);

gtk_container_add( GTK_CONTAINER(window), vbox);

g_signal_connect( G_OBJECT(window), "destroy", G_CALLBACK( gtk_main_quit ), NULL );
g_signal_connect( GTK_BUTTON(btn_get), "clicked",
G_CALLBACK( btn_get_clicked_event ), data );


gtk_widget_show_all( window );
gtk_main();
g_free( data );
return 0;
}

Practice 2: How about a login dialog !




/*
* @author [JaPh]
* @date 30 August, 2009
* @file GtkEntry_02.c
* @site http://xjaphx.blogspot.com/
*/

#include <gtk/gtk.h>
#include <string.h>
#include <glib.h>

typedef struct _DATA {
GtkWidget *widget;
struct _DATA *next;
} DATA;

const char *username = "[JaPh]";
const char *password = "Lesson 14";

void
MessageBox( GtkMessageType type, const char *title, const char *message, const char* details )
{
int res;
GtkWidget *message_box;
message_box = gtk_message_dialog_new( NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
type, GTK_BUTTONS_OK,
message );

gtk_window_set_title( GTK_WINDOW(message_box), "[JaPh]Lesson 14: GtkEntry" );
gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG(message_box), details );

res = gtk_dialog_run( GTK_DIALOG(message_box));
if( res == GTK_RESPONSE_OK ) {
gtk_widget_destroy( message_box );
}
}

void
btn_login_clicked_event( GtkButton *btn_login, DATA *data )
{
if( !strcmp( username, gtk_entry_get_text( data->widget ) ) &&
!strcmp( password, gtk_entry_get_text( data->next->widget )) )
{
MessageBox( GTK_MESSAGE_INFO, "Congratulations!", "Correct!",
"Username and password are correct." );
} else {
MessageBox( GTK_MESSAGE_ERROR, "Fail ", "Incorrect",
"Username and password are incorrect." );
}
}


int
main( int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *hbox_user, *hbox_pass, *hbox_button;
GtkWidget *lbl_user, *lbl_pass;
GtkWidget *txt_user, *txt_pass;
GtkWidget *btn_login, *btn_exit;
DATA *data;

gtk_init( &argc, &argv );

window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title( GTK_WINDOW(window), "[JaPh]Lesson 14: GtkEntry" );
gtk_window_set_default_size( GTK_WINDOW(window), 100, 100 );

lbl_user = gtk_label_new("Username: ");
txt_user = gtk_entry_new();
hbox_user = gtk_hbox_new(TRUE, 5);
gtk_box_pack_start( GTK_BOX(hbox_user), lbl_user, TRUE,TRUE, 5);
gtk_box_pack_start( GTK_BOX(hbox_user), txt_user, TRUE,TRUE, 5);

lbl_pass = gtk_label_new("Password: ");
txt_pass = gtk_entry_new();
/* set invisible character */
gtk_entry_set_invisible_char( GTK_ENTRY(txt_pass), '*' );
/* activate the invisibility mode */
gtk_entry_set_visibility( GTK_ENTRY( txt_pass ), FALSE );
hbox_pass = gtk_hbox_new( TRUE, 5);
gtk_box_pack_start( GTK_BOX(hbox_pass), lbl_pass, TRUE, TRUE, 5);
gtk_box_pack_start( GTK_BOX(hbox_pass), txt_pass, TRUE, TRUE, 5);

btn_login = gtk_button_new_with_mnemonic("_Login");
btn_exit = gtk_button_new_with_mnemonic("E_xit");
hbox_button = gtk_hbox_new( TRUE, 5);
gtk_box_pack_start( GTK_BOX(hbox_button), btn_login, FALSE, TRUE, 20);
gtk_box_pack_start( GTK_BOX(hbox_button), btn_exit, FALSE, TRUE, 20);

vbox = gtk_vbox_new( TRUE, 0);
gtk_box_pack_start( GTK_BOX(vbox), hbox_user, TRUE, TRUE, 0);
gtk_box_pack_start( GTK_BOX(vbox), hbox_pass, TRUE, TRUE, 0);
gtk_box_pack_start( GTK_BOX(vbox), hbox_button, TRUE, TRUE, 0);

data = (DATA *) g_malloc( sizeof( DATA ));
data->widget = txt_user;
data->next = (DATA *) g_malloc( sizeof( DATA ));
data->next->widget = txt_pass;
data->next->next = NULL;

gtk_container_add( GTK_CONTAINER(window), vbox);

g_signal_connect( G_OBJECT(window), "destroy",
G_CALLBACK( gtk_main_quit ), NULL );

g_signal_connect( GTK_BUTTON(btn_login), "clicked",
G_CALLBACK( btn_login_clicked_event ), data );
g_signal_connect( G_OBJECT(btn_exit), "clicked",
G_CALLBACK( gtk_main_quit ), NULL );

gtk_widget_show_all( window );
gtk_main();
g_free(data);
return 0;
}

Well, not much to say but I'm going to create several special sessions next on Gtk+ programming. Make sure you understand all the basics of Gtk+.

Have fun!@

[ Crackme Info ]
Difficulty: 1 - Very easy, for newbies
Platform: Unix/linux etc.
Language: Assembler
Refer: click here
Click to Download

Load into IDA, we have the main program


.text:08048085 mov ebx, 1 ; fd
.text:0804808A mov ecx, offset aPassword ; "\nPassword : "
.text:0804808F mov edx, 0Dh ; len
.text:08048094 int 80h ; LINUX - sys_write
.text:08048096 mov edx, 100h ; len
.text:0804809B mov ecx, offset asc_804911B ; " "
.text:080480A0 mov ebx, 0 ; fd
.text:080480A5 mov eax, 3
.text:080480AA int 80h ; LINUX - sys_read
.text:080480AC mov esi, offset aQtbxctu ; "QTBXCTU"
.text:080480B1 mov edi, esi
.text:080480B3 xor ebx, ebx
.text:080480B5 cld
.text:080480B6
.text:080480B6 loc_80480B6: ; CODE XREF: start+43j
.text:080480B6 lodsb
.text:080480B7 xor al, 21h
.text:080480B9 stosb
.text:080480BA inc ebx
.text:080480BB cmp ebx, 7
.text:080480C1 jz short loc_80480C5
.text:080480C3 loop loc_80480B6
.text:080480C5
.text:080480C5 loc_80480C5: ; CODE XREF: start+41j
.text:080480C5 mov esi, offset asc_804911B ; " "
.text:080480CA mov edi, offset aQtbxctu ; "QTBXCTU"
.text:080480CF mov ecx, 7
.text:080480D4 cld
.text:080480D5 repe cmpsb
.text:080480D7 jnz short loc_80480EF
.text:080480D9 mov eax, 4
.text:080480DE mov ebx, 1 ; status
.text:080480E3 mov ecx, offset unk_8049105 ; addr
.text:080480E8 mov edx, 16h ; len
.text:080480ED int 80h ; LINUX - sys_write
.text:080480EF
.text:080480EF loc_80480EF: ; CODE XREF: start+57j
.text:080480EF mov eax, 1
.text:080480F4 int 80h ; LINUX - sys_exit
.text:080480F4 start endp
.text:080480F4
.text:080480F4 _text ends
.text:080480F4

Each bytes of our input password is encrypted:

.text:080480B6 loc_80480B6: ; CODE XREF: start+43j
.text:080480B6 lodsb
.text:080480B7 xor al, 21h
.text:080480B9 stosb
.text:080480BA inc ebx
.text:080480BB cmp ebx, 7
.text:080480C1 jz short loc_80480C5
.text:080480C3 loop loc_80480B6

So, the real password can be found if we decrypt the string "QTBXCTU".
The encryption is simple, each byte is XORed w/ 0x21.
Then, we also use XORed w/ 0x21 to decrypt it.
Here a little perl script I wrote to decrypt.

#!/usr/bin/perl
my $cipher_txt = "QTBXCTU";
my $plain_txt;

my @arr = unpack("C*", $cipher_txt);
foreach my $c (@arr) {
$plain_txt .= chr( $c ^ 0x21 );
}

print $plain_txt, "\n";


Have fun!@

This is my little video guide through the wargame of SmashTheStack.Org

Wargame: SmashTheStack.Org | IO | Level 5
Creator: [JaPh]
Video: [ OGV | Length: 18.08 min | 72.1 MB | Super High Quality ]
Download: Rapidshare
Password: [japh]

Have fun!@

I use these crackmes as a practice for reversing and debugging skills. However, any time I solve a crackme, I make a post as a guide for those who have the same interest as me and have troubles with them.
These crackmes are dedicated to run under Linux environment only, not Windows.
I collect these crackmes on crackmes.de site, so I can visit that site and check out for information.
Hope this would be helpful to someone.

[Level: EASIEST, FOR NEWBIES ONLY]

Guide to crack "Easy Linux Crackme" by lord
Solve cyrex's Linux CrackMe
Solve cyrex's Linux Crackme02
Solve dynsym's Crackme
Solve intsig's Easymath
Solve Qnix's qcrk5
Solve cli3nt's mycrk
Solve lord's Easy Crackme 2

[ to be updated...]

Have fun!@

==:: Crackme Info ::==
Difficulty: 1 - Very easy, for newbies
Platform: Unix/linux etc.
Language: C/C++
Refer: click here
Click to Download

Use GDB to disassemble the main function


0x080483c4 <main+0>: push %ebp
0x080483c5 <main+1>: mov %esp,%ebp
0x080483c7 <main+3>: sub $0x18,%esp
0x080483ca <main+6>: and $0xfffffff0,%esp
0x080483cd <main+9>: mov $0x0,%eax
0x080483d2 <main+14>: sub %eax,%esp
0x080483d4 <main+16>: movl $0x11e67,-0x4(%ebp)
0x080483db <main+23>: movl $0x5b1270,-0x8(%ebp)
0x080483e2 <main+30>: movl $0x6,-0x10(%ebp)
0x080483e9 <main+37>: sub $0xc,%esp
0x080483ec <main+40>: push $0x8048514
0x080483f1 <main+45>: call 0x80482e4 <printf@plt>
0x080483f6 <main+50>: add $0x10,%esp
0x080483f9 <main+53>: sub $0x8,%esp
0x080483fc <main+56>: lea -0xc(%ebp),%eax
0x080483ff <main+59>: push %eax
0x08048400 <main+60>: push $0x8048522
0x08048405 <main+65>: call 0x80482c4 <scanf@plt>
0x0804840a <main+70>: add $0x10,%esp
0x0804840d <main+73>: mov -0x8(%ebp),%eax
0x08048410 <main+76>: cmp -0xc(%ebp),%eax
0x08048413 <main+79>: jne 0x8048432 <main+110>
0x08048415 <main+81>: mov -0x10(%ebp),%edx
0x08048418 <main+84>: lea -0x4(%ebp),%eax
0x0804841b <main+87>: xor %edx,(%eax)
0x0804841d <main+89>: sub $0x8,%esp
0x08048420 <main+92>: pushl -0x4(%ebp)
0x08048423 <main+95>: push $0x8048525
0x08048428 <main+100>: call 0x80482e4 <printf@plt>
0x0804842d <main+105>: add $0x10,%esp
0x08048430 <main+108>: jmp 0x8048442 <main+126>
0x08048432 <main+110>: sub $0xc,%esp
0x08048435 <main+113>: push $0x8048529
0x0804843a <main+118>: call 0x80482e4 <printf@plt>
0x0804843f <main+123>: add $0x10,%esp
0x08048442 <main+126>: mov $0x0,%eax
0x08048447 <main+131>: leave
0x08048448 <main+132>: ret

So,
[ebp-4] = 0x11E67
[ebp-8] = 0x5b1270
[ebp-c] is our input key

the comparison check

0x0804840d <main+73>: mov -0x8(%ebp),%eax
0x08048410 <main+76>: cmp -0xc(%ebp),%eax
0x08048413 <main+79>: jne 0x8048432 <main+110>

So easy, the real key is hardcoded, and it is at [ebp-8] = 0x5b1270, which is 5968496 in decimal.
If equal, the [ebp-4] is calculated

0x08048415 <main+81>: mov -0x10(%ebp),%edx
0x08048418 <main+84>: lea -0x4(%ebp),%eax
0x0804841b <main+87>: xor %edx,(%eax)

After XOR, the value of eax is 0x11E61, which is 73313 in decimal.
If wrong, the message "wrong" is output.
This is a good easy crackme for newbie.

Have fun!@

==:: Crackme Info ::==
Difficulty: 1 - Very easy, for newbies
Platform: Unix/linux etc.
Language: C/C++
Refer: click me
Click to Download

This crackme is in fact pretty tough for beginner, like me gigitjari. Since it's built in static mode, everything's just look very confusing.
I will use IDA, then go to the Entry Point of main function.
Here it is


.text:08048208
.text:08048208 ; Attributes: bp-based frame
.text:08048208
.text:08048208 sub_8048208 proc near ; DATA XREF: start+17o
.text:08048208
.text:08048208 var_28 = dword ptr -28h
.text:08048208 var_24 = dword ptr -24h
.text:08048208 var_20 = dword ptr -20h
.text:08048208 var_1C = dword ptr -1Ch
.text:08048208 var_14 = dword ptr -14h
.text:08048208 var_8 = dword ptr -8
.text:08048208 var_4 = dword ptr -4
.text:08048208 arg_0 = dword ptr 8
.text:08048208 arg_4 = dword ptr 0Ch
.text:08048208
.text:08048208 push ebp
.text:08048209 mov ebp, esp
.text:0804820B sub esp, 28h
.text:0804820E and esp, 0FFFFFFF0h
.text:08048211 mov eax, 0
.text:08048216 add eax, 0Fh
.text:08048219 add eax, 0Fh
.text:0804821C shr eax, 4
.text:0804821F shl eax, 4
.text:08048222 sub esp, eax
.text:08048224 mov [ebp+var_4], 4B7F3DA0h
.text:0804822B mov [esp+28h+var_1C], 0
.text:08048233 mov [esp+28h+var_20], 1
.text:0804823B mov [esp+28h+var_24], 0
.text:08048243 mov [esp+28h+var_28], 0
.text:0804824A call sub_804EA50
.text:0804824F test eax, eax
.text:08048251 jns short loc_8048260
.text:08048253 mov eax, 1
.text:08048258 mov [ebp+var_14], eax
.text:0804825B jmp loc_8048335
.text:08048260 ; ---------------------------------------------------------------------------
.text:08048260
.text:08048260 loc_8048260: ; CODE XREF: sub_8048208+49j
.text:08048260 cmp [ebp+arg_0], 2
.text:08048264 jz short loc_8048291
.text:08048266 mov eax, [ebp+arg_4]
.text:08048269 mov eax, [eax]
.text:0804826B mov edx, off_80AF3B4
.text:08048271 mov [esp+28h+var_20], eax
.text:08048275 mov [esp+28h+var_24], offset aUsageSPassword ; "Usage : %s \n"
.text:0804827D mov [esp+28h+var_28], edx
.text:08048280 call sub_8049530
.text:08048285 mov [esp+28h+var_28], 0
.text:0804828C call sub_8048C10
.text:08048291 ; ---------------------------------------------------------------------------
.text:08048291
.text:08048291 loc_8048291: ; CODE XREF: sub_8048208+5Cj
.text:08048291 mov eax, [ebp+arg_4]
.text:08048294 add eax, 4
.text:08048297 mov eax, [eax]
.text:08048299 mov [esp+28h+var_28], eax
.text:0804829C call sub_8048BE0
.text:080482A1 mov [ebp+var_8], eax
.text:080482A4 lea eax, [ebp+var_8]
.text:080482A7 add dword ptr [eax], 5
.text:080482AA lea eax, [ebp+var_8]
.text:080482AD add dword ptr [eax], 60h
.text:080482B0 mov edx, [ebp+var_8]
.text:080482B3 mov eax, edx
.text:080482B5 shl eax, 8
.text:080482B8 sub eax, edx
.text:080482BA mov [ebp+var_8], eax
.text:080482BD mov eax, [ebp+var_8]
.text:080482C0 imul eax, 909090h
.text:080482C6 mov [ebp+var_8], eax
.text:080482C9 mov eax, [ebp+arg_4]
.text:080482CC add eax, 4
.text:080482CF mov eax, [eax]
.text:080482D1 mov edx, off_80AF3B4
.text:080482D7 mov [esp+28h+var_20], eax
.text:080482DB mov [esp+28h+var_24], offset aUsingS ; "Using %s\n"
.text:080482E3 mov [esp+28h+var_28], edx
.text:080482E6 call sub_8049530
.text:080482EB mov eax, [ebp+var_4]
.text:080482EE cmp eax, [ebp+var_8]
.text:080482F1 jnz short loc_8048314
.text:080482F3 mov eax, off_80AF3B4
.text:080482F8 mov [esp+28h+var_24], offset aCorrectCracked ; "Correct, Cracked !!\n"
.text:08048300 mov [esp+28h+var_28], eax
.text:08048303 call sub_8049530
.text:08048308 mov [esp+28h+var_28], 0
.text:0804830F call sub_8048C10
.text:08048314 ; ---------------------------------------------------------------------------
.text:08048314
.text:08048314 loc_8048314: ; CODE XREF: sub_8048208+E9j
.text:08048314 mov eax, off_80AF3B4
.text:08048319 mov [esp+28h+var_24], offset aWrong ; "Wrong!\n"
.text:08048321 mov [esp+28h+var_28], eax
.text:08048324 call sub_8049530
.text:08048329 mov [esp+28h+var_28], 0
.text:08048330 call sub_8048C10
.text:08048335 ; ---------------------------------------------------------------------------
.text:08048335
.text:08048335 loc_8048335: ; CODE XREF: sub_8048208+53j
.text:08048335 mov eax, [ebp+var_14]
.text:08048338 leave
.text:08048339 retn
.text:08048339 sub_8048208 endp
.text:08048339
.text:08048339 ;

This is where the input is compared

.text:080482EB mov eax, [ebp+var_4]
.text:080482EE cmp eax, [ebp+var_8]
.text:080482F1 jnz short loc_8048314

There have 2 solutions here as usual: Patch & Keygen

1. Patch:
- Just do this as a practice since author doesn't allow patching. For beginners, it's good to know how to patch as well.
- We patch the Jump at 0x080482F1 from: 75 21 to: 90 90

2. Keygen:
- Look at the code flow, you can see [ebp+var_4] doesn't change in main. Its value is assigned at beginning:

.text:08048224 mov [ebp+var_4], 4B7F3DA0h

- The translation of disassembly part

.text:08048291 mov eax, [ebp+arg_4]
.text:08048294 add eax, 4
.text:08048297 mov eax, [eax]
.text:08048299 mov [esp+28h+var_28], eax
.text:0804829C call sub_8048BE0 ; atoi( argv[1] )
.text:080482A1 mov [ebp+var_8], eax ; var_8 = atoi( arv[1] )
.text:080482A4 lea eax, [ebp+var_8] ; eax = var_8
.text:080482A7 add dword ptr [eax], 5 ; eax += 5
.text:080482AA lea eax, [ebp+var_8]
.text:080482AD add dword ptr [eax], 60h ; eax += 60
.text:080482B0 mov edx, [ebp+var_8] ; edx = var_8
.text:080482B3 mov eax, edx ; eax = edx
.text:080482B5 shl eax, 8 ; eax <<= 8
.text:080482B8 sub eax, edx ; eax = eax - edx
.text:080482BA mov [ebp+var_8], eax
.text:080482BD mov eax, [ebp+var_8] ; eax = var_8
.text:080482C0 imul eax, 909090h ; eax = eax * 909090
.text:080482C6 mov [ebp+var_8], eax ; var_8 = eax
.text:080482C9 mov eax, [ebp+arg_4]
.text:080482CC add eax, 4
.text:080482CF mov eax, [eax]
.text:080482D1 mov edx, off_80AF3B4
.text:080482D7 mov [esp+28h+var_20], eax
.text:080482DB mov [esp+28h+var_24], offset aUsingS ; "Using %s\n"
.text:080482E3 mov [esp+28h+var_28], edx
.text:080482E6 call sub_8049530
.text:080482EB mov eax, [ebp+var_4] ; var_4 = 4B7F3DA0
.text:080482EE cmp eax, [ebp+var_8] ; var_8
.text:080482F1 jnz short loc_8048314

Here is the simple keygen written in C

#include <stdio.h>

unsigned int
compute( unsigned int i )
{
register unsigned int x, y;
x = y = (i + 0x65);
x <<= 8;
x -= y;
x *= 0x909090;
return x;
}

int
main( int argc, char *argv[] )
{
unsigned int i = 0;
const int TARGET = 0x4B7F3DA0;
while( i < 0xFFFFFFFF ) {
if( compute(i) == TARGET ) {
printf("[+] Found: %u \n", i);
}
++i;
}
return 0;
}

Have fun!@

==:: Crackme Info ::==
Difficulty: 1 - Very easy, for newbies
Platform: Unix/linux etc.
Language: C/C++
Refer: click here
Click to Download

The crackme will only print 'done' message if we get the correct password only.
This crackme seems to be very complicated. If you try to dump it with Dasm2 or load through GDB, it certainly doesn't work at all.
We use readelf to look at its header information


$ readelf -e easymath
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x8048380
Start of program headers: 52 (bytes into file)
Start of section headers: 0 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 7
Size of section headers: 0 (bytes)
Number of section headers: 0
Section header string table index: 0 <corrupt: out of range>

There are no sections in this file.

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4
INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x00644 0x00644 R E 0x1000
LOAD 0x000644 0x08049644 0x08049644 0x00110 0x00114 RW 0x1000
DYNAMIC 0x000658 0x08049658 0x08049658 0x000c8 0x000c8 RW 0x4
NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4

It's not looking good at all.
Let's load it with IDA. Here a little view:


Jump to entry point of program: Ctrl+E -> start

LOAD:08048380 ; Attributes: noreturn
LOAD:08048380
LOAD:08048380 public start
LOAD:08048380 start proc near
LOAD:08048380 xor ebp, ebp
LOAD:08048382 pop esi
LOAD:08048383 mov ecx, esp
LOAD:08048385 and esp, 0FFFFFFF0h
LOAD:08048388 push eax
LOAD:08048389 push esp
LOAD:0804838A push edx
LOAD:0804838B push offset sub_8048580
LOAD:08048390 push offset sub_8048510
LOAD:08048395 push ecx
LOAD:08048396 push esi
LOAD:08048397 push offset sub_8048438
LOAD:0804839C call sub_8048344
LOAD:080483A1 hlt
LOAD:080483A1 start endp

So, the OEP of main() is call

LOAD:08048397 push offset sub_8048438

Jump to main() [G: 8048438]

Scroll down a bit:

LOAD:0804849E loc_804849E: ; CODE XREF: sub_8048438+47j
LOAD:0804849E mov [ebp+var_10], 6
LOAD:080484A5 mov [ebp+var_C], 2
LOAD:080484AC mov [ebp+var_8], 0
LOAD:080484B3 mov [ebp+var_4], 4530h
LOAD:080484BA mov eax, [ebp+arg_4]
LOAD:080484BD add eax, 4
LOAD:080484C0 mov eax, [eax]
LOAD:080484C2 sub esp, 0Ch
LOAD:080484C5 push eax
LOAD:080484C6 call sub_8048354
LOAD:080484CB add esp, 10h
LOAD:080484CE mov [ebp+var_14], eax
LOAD:080484D1 nop
LOAD:080484D2 mov eax, [ebp+var_10]
LOAD:080484D5 mov edx, eax
LOAD:080484D7 imul edx, [ebp+var_C]
LOAD:080484DB mov eax, [ebp+var_14]
LOAD:080484DE imul eax, edx
LOAD:080484E1 mov [ebp+var_8], eax
LOAD:080484E4 xor eax, eax
LOAD:080484E6 mov eax, [ebp+var_4]
LOAD:080484E9 cmp eax, [ebp+var_8]
LOAD:080484EC jnz short loc_80484FE
LOAD:080484EE sub esp, 0Ch
LOAD:080484F1 push offset aDone ; "done"
LOAD:080484F6 call sub_8048324
LOAD:080484FB add esp, 10h

So, the comparison is at: 0x080484E9 and the jump is below.
There're two ways to solve this problem: Patch & KeyGen

1. Patch:
- We will NOP at the jump. The offset of the jump is at 0x4EC
- Load hexedit

$ hexedit easymath

Press {Enter} then type the offset: 0x4EC
- We patch 2 bytes: 75 10 into 90 90
F2 to save then F10 (or Ctrl+X) to quit.
- Run crackme with any-value argument

2. Keygen:
- Take a closer look at disassembly code above, I explain them like this:


LOAD:0804849E mov [ebp+var_10], 6 ; var_10 = 6
LOAD:080484A5 mov [ebp+var_C], 2 ; var_C = 2
LOAD:080484AC mov [ebp+var_8], 0 ; var_8 = 0
LOAD:080484B3 mov [ebp+var_4], 4530h ; var_4 = 4530
LOAD:080484BA mov eax, [ebp+arg_4]
LOAD:080484BD add eax, 4
LOAD:080484C0 mov eax, [eax]
LOAD:080484C2 sub esp, 0Ch
LOAD:080484C5 push eax
LOAD:080484C6 call sub_8048354 ; atoi( argv[1] )
LOAD:080484CB add esp, 10h
LOAD:080484CE mov [ebp+var_14], eax ; var_14 = atoi( argv[1] )
LOAD:080484D1 nop
LOAD:080484D2 mov eax, [ebp+var_10] ; eax = var_10 = 6
LOAD:080484D5 mov edx, eax ; edx = eax = 6
LOAD:080484D7 imul edx, [ebp+var_C] ; edx = edx * var_C = 6 * 2 = C
LOAD:080484DB mov eax, [ebp+var_14] ; eax = var_14
LOAD:080484DE imul eax, edx ; eax = eax * edx = var_14 * C
LOAD:080484E1 mov [ebp+var_8], eax ; var_8 = eax = var_14 * C
LOAD:080484E4 xor eax, eax ; eax = 0
LOAD:080484E6 mov eax, [ebp+var_4] ; eax = var_4
LOAD:080484E9 cmp eax, [ebp+var_8] ; eax == var_8 ?
LOAD:080484EC jnz short loc_80484FE ; 0x080484EC if true : 0x80484FE else
LOAD:080484EE sub esp, 0Ch
LOAD:080484F1 push offset aDone ; "done"
LOAD:080484F6 call sub_8048324
LOAD:080484FB add esp, 10h

As you can see, var_14 is our input as argv[1]. So it must be the number N that satisfies the equation: N * C = 4530 (in hex).
So, N = 5C4 or 1476 in decimal.
Try it

$ ./easymath 1476
done

That's all for this crackme.

Have fun!@

This is so fun gelakguling


Now, it's time to study the next useful widget ever, GtkTable.
GtkTable is a layout widget that contains its children's widgets in a table.
Reference GtkTable

GtkTable has 5 properties:

  1. Number of columns
  2. Number of rows
  3. Column spacing
  4. Row spacing
  5. Homogeneous

To create a new table:

GtkWidget *table;
table = gtk_table_new( 2, 2, TRUE );

whereas, the first two params are number of rows and columns in table, the last param indicates whether children should be homogeneous.

The most important part is to handle and pack the children's widgets into the table.
There are two methods we can use to pack:
  1. gtk_table_attach()
  2. gtk_table_attach_defaults()
The first method is used generally because as you see the second methods are simply just pre-settings of the first method, it pre-define GTK_EXPAND | GTK_FILL and set 0-spacing for all cells. So, just in case when you really need your application to have all children being identical, you will use gtk_table_attach_defaults(); otherwise, you must use gtk_table_attach() to specify children's settings properly.
Reference GtkAttachOptions

Now, assume you want to pack a child into the first row, second column, do this:

gtk_table_attach( GTK_TABLE(table), child_widget, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );

The last four params are to specify vertical and horizontal settings including paddings.

Let's do a small practice:

Practice 1: Place 4 label with appropriate coordinate into a table, use defaults attaching settings.

/*
* @author [JaPh]
* @date 23 August, 2009
* @file GtkTable_01.c
* @site http://xjaphx.blogspot.com/
*/

#include <gtk/gtk.h>

int
main ( int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *table;
GtkWidget *lbl1, *lbl2, *lbl3, *lbl4;

gtk_init( &argc, &argv );

window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title(GTK_WINDOW(window), "[JaPh]Lesson 12: GtkTable");
gtk_window_set_default_size( GTK_WINDOW( window ), 100, 100);

table = gtk_table_new(2, 2, TRUE );

/* set label w/ appropriate coordinates */
lbl1 = gtk_label_new("1,1");
lbl2 = gtk_label_new("1,2");
lbl3 = gtk_label_new("2,1");
lbl4 = gtk_label_new("2,2");

/* attach to table following its coordinates */
gtk_table_attach_defaults( GTK_TABLE(table), lbl1, 0,1,0,1);
gtk_table_attach_defaults( GTK_TABLE(table), lbl2, 1,2,0,1);
gtk_table_attach_defaults( GTK_TABLE(table), lbl3, 0,1,1,2);
gtk_table_attach_defaults( GTK_TABLE(table), lbl4, 1,2,1,2);

gtk_container_add( GTK_CONTAINER(window), table );

g_signal_connect( G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

gtk_widget_show_all( window );

gtk_main();
return 0;
}

Practice 2: Let's use this GtkTable layout to do the practice on previous lesson 11.



/*
* @author [JaPh]
* @date 23 August, 2009
* @file GtkTable_02.c
* @site http://xjaphx.blogspot.com/
*/

#include <gtk/gtk.h>

/* declare a message box widget */
GtkWidget *msg_box;

/* construct a message box dialog */
void
MessageBox( GtkMessageType mType, GtkButtonsType bType, const gchar *title,
const gchar *msg, const gchar *details )
{
/* message box response code */
int res;
/* create a message box dialog */
msg_box = gtk_message_dialog_new( NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
mType, bType, msg );
/* set message box title */
gtk_window_set_title( GTK_WINDOW( msg_box ), title );
/* set detail text */
gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( msg_box ), details );
/* run the message box dialog */
res = gtk_dialog_run( GTK_DIALOG( msg_box ) );
/* check for dialog response and handle */
if( res == GTK_RESPONSE_OK )
gtk_widget_destroy( msg_box );
}

void
btn_info_clicked( GtkButton *btn, gpointer data )
{
MessageBox( GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "[JaPh] Dialog: INFO" ,
"GtkMessageDialog: Info", "Option: GTK_FILL; Spacing: 5,5; Coord: 0,0" );
}
void
btn_warn_clicked( GtkButton *btn, gpointer data )
{
MessageBox( GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "[JaPh] Dialog: WARNING",
"GtkMessageDialog: Warning", "Option: GTK_FILL; Spacing: 5,5; Coord: 0,1" );
}
void
btn_ques_clicked( GtkButton *btn, gpointer data )
{
MessageBox( GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK, "[JaPh] Dialog: QUESTION",
"GtkMessageDialog: Question", "Option: GTK_FILL; Spacing: 5,5; Coord: 1,0" );
}
void
btn_erro_clicked( GtkButton *btn, gpointer data )
{
MessageBox( GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "[JaPh] Dialog: ERROR",
"GtkMessageDialog: Error", "Option: GTK_FILL; Spacing: 5,5; Coord: 1,1" );
}

int
main( int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *table;
GtkWidget *btn_info, *btn_warn,
*btn_ques, *btn_erro;
GtkWidget *btn_exit;

gtk_init( &argc, &argv );

window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title( GTK_WINDOW(window), "[JaPh]Lesson 12: GtkTable" );
gtk_window_set_default_size( GTK_WINDOW(window), 300, 300 );

table = gtk_table_new( 3, 2, TRUE );

btn_info = gtk_button_new_with_mnemonic("I_nformation");
btn_warn = gtk_button_new_with_mnemonic("W_arning");
btn_ques = gtk_button_new_with_mnemonic("Q_uestion");
btn_erro = gtk_button_new_with_mnemonic("E_rror");
btn_exit = gtk_button_new_with_mnemonic("E_xit");

gtk_table_attach( GTK_TABLE(table), btn_info,
0, 1, 0, 1,
GTK_FILL, GTK_FILL,
5, 5 );
gtk_table_attach( GTK_TABLE(table), btn_warn,
1, 2, 0, 1,
GTK_FILL, GTK_FILL,
5, 5 );
gtk_table_attach( GTK_TABLE(table), btn_ques,
0, 1, 1, 2,
GTK_FILL, GTK_FILL,
5, 5 );
gtk_table_attach( GTK_TABLE(table), btn_erro,
1, 2, 1, 2,
GTK_FILL, GTK_FILL,
5, 5 );
gtk_table_attach( GTK_TABLE(table), btn_exit,
0, 2, 2, 3,
GTK_FILL | GTK_EXPAND, GTK_FILL,
5, 5 );

g_signal_connect( GTK_BUTTON( btn_info ), "clicked",
G_CALLBACK( btn_info_clicked ), NULL );
g_signal_connect( GTK_BUTTON( btn_warn ), "clicked",
G_CALLBACK( btn_warn_clicked ), NULL );
g_signal_connect( GTK_BUTTON( btn_ques ), "clicked",
G_CALLBACK( btn_ques_clicked ), NULL );
g_signal_connect( GTK_BUTTON( btn_erro ), "clicked",
G_CALLBACK( btn_erro_clicked ), NULL );

g_signal_connect( GTK_BUTTON(btn_exit), "clicked",
G_CALLBACK( gtk_main_quit ), NULL );
g_signal_connect( G_OBJECT(window), "destroy",
G_CALLBACK( gtk_main_quit ), NULL );

gtk_container_add( GTK_CONTAINER(window), table );

gtk_widget_show_all( window );

gtk_main();
return 0;
}

It's the end of Lesson 12.

Have fun!@

==:: Crackme Info ::==
Difficulty: 1 - Very easy, for newbies
Platform: Unix/linux etc.
Language: C/C++
Refer: click me
Click to Download

Disassembly main() function to see what's going on.


(gdb) disas main

Look at this

0x080484b0 : movl $0x80485e3,(%esp)
0x080484b7 : call 0x804831c

This is the string: [!] Solved!
Look up a little bit, we can see

0x0804846c : mov $0xa,%ecx
0x08048471 : mov 0x4(%edx),%esi
0x08048474 : repz cmpsb %es:(%edi),%ds:(%esi)
0x08048476 : je 0x80484b0

It's how it goes.
There's a byte-to-byte comparison at EDI and ESI, up to 0x0A bytes then jump if they're still equal to each other; then, it certainly prints the good message. Otherwise, it will fail.

There're solution you can do at this point.
1. Patch the Jump
2. Check for string in EDI

Let's do both of these as a practice.

1. Patching:

$ gdb --write -nx -q crackme1
(gdb) x/x 0x8048474
0x8048474 : 0x3874a6f3
(gdb) set {int} 0x8048474 = 0x38749090
(gdb) q
$ ./crackme1
[!] Solved!

2. Trace through EDI
- Set breakpoint at main+65 then run

(gdb) x/s $edi
0x80485d4: "__gmon_start__"

ok..since it compares only 10 bytes, then we just need to pass our arguments as: __gmon_sta is enough or whatever is next the string.

Have fun!@


I caught this one sembah. Is this kind of joke?

It's just that, he is good and very kind. He doesn't seem to write blogs much but his blog is full of good articles and nice explanation. He's from where I'm currently living in. Even though his language is hard but I still try to understand what he writes on the blog.
We both have the same interests. I have many questions but he does answer clearly well, and just for a short time, I've understood so many things that I couldn't do it before. I'm limited but I believe I will become better, credit to him.

Badcob, thanks for your support!

Be Blessings,
[JaPh]

Let say you have some Bin/Cue files and you don't like it, you're under Linux and don't want to emulate every time you run the file...or whatever reasons you have; you definitely want to either extract it or convert into another easier-to-use file format.
For me, to-ISO conversion is a good pick-up.

The tool is used for conversion is called bchunk.

Assuming you have fileX.bin and fileX.cue, in order to convert them into ISO format use this command below:


$ bchunk -v fileX.bin fileX.cue fileX

fileX is the name output of the ISO file after conversion.
The speed of conversion is pretty amazing. I've converted 4 GB for about 3 min 28 seconds. Pretty cool, isn't it?
Next is just to mount your newly-created ISO file.

$ mount -o loop iso9660 fileX.sio /mnt/iso_mnt_dir

Have fun!@

Here a simple example of exporting C function to Nasm.


;
; @author [JaPh]
; @date 17 August, 2009
; @file 1.asm
; @site http://xjaphx.blogspot.com/
;
; @command
; assemble nasm -f elf -l 1.lst 1.asm
; link gcc -o 1 1.o
; run ./1
;

extern printf

SECTION .data

message: db "[JaPh]Hello World",0

SECTION .text

global main ; entry point

main:
push ebp
mov ebp, esp

push dword message ; address of 'message'
call printf ; printf()
add esp, 4 ; 1 push = 4 bytes

mov esp, ebp
pop ebp

mov eax, 0
ret

The equivalent program written in C

#include <stdio.h>

int
main( int argc, char *argv[] )
{
printf("[JaPh]Hello World");
return 0
}


Have fun!@

Difficulty: 1 - Very easy, for newbies
Platform: Unix/linux etc.
Language: C/C++
Link: Click to refer
Click to Download

Try to run it first to see how it works.
Then launch gdb. Check out for function symbols


(gdb) info func
0x080483b0 __register_frame_info
0x080483b0 __register_frame_info@plt
0x080483c0 strcmp@plt
0x080483d0 scanf@plt
0x080483e0 __deregister_frame_info
0x080483e0 __deregister_frame_info@plt
0x080483f0 ptrace@plt
0x08048400 __libc_start_main@plt
0x08048410 printf@plt
0x08048420 exit@plt
0x08048430 fopen@plt

Hum....strcmp() and fopen() are called, then must be something about the real password comparison and file operation.
Boom...this crackme calls ptrace(), why?
Let's try to set breakpoint at strcmp() and fopen()

(gdb) b 0x080483c0
(gdb) b 0x08048430
(gdb) run
Are you trying to Debug me?

Bang ! So this crackme calls ptrace() for anti-debugging.

Quit gdb. We switch into dasm2.
Disassembly it:

$ dasm2 crackme -output=dump


push $8048800 ; reference to data : "-[ Linux CrackMe (Level:3) by cyrex ]-"

call 08048410 ;
add $10,%esp ;
add $fffffff4,%esp ;
push $8048840 ; reference to data : "-[ TODO: Get the valid password ]-"

call 08048410 ;
add $10,%esp ;
add $fffffff4,%esp ;
push $8048868 ; reference to data : "-[ Enter Password: "

call 08048410 ;
add $10,%esp ;
add $fffffff8,%esp ;
lea -400(%ebp),%eax ;
push %eax ;
push $804887c ; reference to data : "%s"

call 080483d0 ;
add $10,%esp ;
add $fffffff8,%esp ;
lea -400(%ebp),%eax ;
push %eax ;
push $804887f ; reference to data : "-[ Entered Password: %s"

call 08048410 ;
add $10,%esp ;
add $fffffff4,%esp ;
push $8048898 ; reference to data : "-[ Checking Stage 1 Now....."

call 08048410 ;
add $10,%esp ;
add $fffffff8,%esp ;
push $80488b6 ; reference to data : "7gb5fjf8v4bg8fb34f"

lea -400(%ebp),%eax ;
push %eax ;
call 080483c0 ;
add $10,%esp ;
mov %eax,%eax ;
test %eax,%eax ;
jne 08048600 ;
add $fffffff4,%esp ;
push $80488c9 ; reference to data : "-[ Stage 1 Cleared"

call 08048410 ;
add $10,%esp ;
jmp 08048614 ;
lea 0(%esi),%esi ;
add $fffffff4,%esp ; referenced from jump(s) at 080485e9;

push $80488dd ; reference to data : "-[ Game Over"

call 08048410 ;
add $10,%esp ;
xor %eax,%eax ;
jmp 08048690 ;
add $fffffff4,%esp ; referenced from jump(s) at 080485fb;

push $80488eb ; reference to data : "-[ Checking Stage 2 Now...."

call 08048410 ;
add $10,%esp ;
add $fffffff8,%esp ;
push $8048908 ; reference to data : "r"

push $8048920 ; reference to data : "/tmp/crackme_89nfnjfiefheufeue"

call 08048430 ;
add $10,%esp ;
mov %eax,%eax ;
mov %eax,-404(%ebp) ;
cmpl $0,-404(%ebp) ; reference to data : "__gmon_start__"

jne 08048667 ;
add $fffffff4,%esp ;
push $8048940 ; reference to data : "-[ Bad did you forgot something?"

call 08048410 ;
add $10,%esp ;
add $fffffff4,%esp ;
push $0 ; reference to data : "__gmon_start__"

call 08048420 ;
add $10,%esp ;
add $fffffff4,%esp ; referenced from jump(s) at 08048648;

push $8048980 ; reference to data : "-[ You have successfully reversed/cracked/sniffed This Crackme"

call 08048410 ;
add $10,%esp ;
add $fffffff4,%esp ;
push $80489c0 ; reference to data : "-[ Email me your solution to eth0@list.ru"


So the first password is: "7gb5fjf8v4bg8fb34f"
And then because it reads a file "/tmp/crackme_89nfnjfiefheufeue" (not writing), if the file exists, then good message shows; otherwise, fail.

Have fun!@

[ Crackme Info ]
Difficulty: 1 - Very easy, for newbies
Platform: Unix/linux etc.
Language: C/C++
Links: Click to refer
Click to Download

First, run the crackme, it requires to input the right password.
Launch gdb


$ gdb crackme

Check function symbols

(gdb) info func
0x0804831c strcmp
0x08048450 main


Look over main function

(gdb) disas main

We see this part:

0x0804849d : push $0x80486a4
0x080484a2 : lea -0x20(%ebp),%eax
0x080484a5 : push %eax
0x080484a6 : call 0x804831c

So, the address 0x80486a4 may contain the real password
Let's check it.

(gdb) b *main+86
(gdb) run

After input, it stops at our breakpoint.
First, have a look at EAX

(gdb) x/s $eax
0xbfc5a498: "japhcracker"

This is our input, let see the value at 0x80486a4

(gdb) x/s 0x80486a4
0x80486a4: "47ghf6fh37fbgbgj"

Exit gdb, run the program and input the above string. It must be the password.

Have fun!@

whole day spent with wargames....exhausted..hungry...

This is my little video guide through the wargame of SmashTheStack.Org

Wargame: SmashTheStack.Org | IO | Level 4
Creator: [JaPh]
Video: [ OGV | Length: 10.50 min | 31.8 MB | Super High Quality ]
Download: Rapidshare
Password: [japh]

Have fun!@

Now, I will introduce you a very, very popular widget that is used most of the time, GtkMessageDialog.

As you use software, sometimes it will pops up a small dialog that contains message which can be in types of either about Information, or Warning, or Question, or Error.
Like this:

Under Windows, it's known as MessageBox, right? You might be familiar with this Message Box already.

Let's look over its documentation.
Reference GtkMessageDialog

First of all, in the inherited hierarchy, GtkMessageDialog is from GtkDialog, so it certainly contains all the properties and accessing methods of GtkDialog. Simply, it's a pre-decorated dialog.

Secondly, these are the properties that you need to consider when creating a MessageDialog:
[+] Title: inherited from GtkWindow
[+] Dialog Flags: either GTK_DIALOG_MODAL or GTK_DIALOG_DESTROY_WITH_PARENT
[+] Message Type: is one of the four: GTK_MESSAGE_INFO, GTK_MESSAGE_WARNING, GTK_MESSAGE_QUESTION, GTK_MESSAGE_ERROR
[+] Button Type: either GTK_BUTTONS_*{ NONE, OK, CLOSE, CANCEL, YES_NO, OK_CANCEL } or you can create and add your own button by gtk_dialog_add_buttons().
[+] Secondary Text: is the detail info what you want to describe.

[!] 'Til now, since I haven't introduced about GtkDialog, but just stick with what I mention below:
- use gtk_dialog_run() to run the message dialog.
- gtk_dialog_run() return a response signal, therefore, always try to handle the signal.
- always use gtk_widget_destroy() to close message dialog, to avoid memory leak.
Some reference you need to read about what I mentioned:
Reference gtk_dialog_run()
Reference GtkResponseType

So far, it's enough for you at the present.

Practice: write a Gtk+ application that contains 4 buttons that will emits different types of GtkMessageDialog.


Try to read documentation and what I've mentioned so far then make your code. Make it simple and clear.

Below is my source for reference:


/*
* @author [JaPh]
* @date 15 August, 2009
* @file GtkMessageDialog_01.c
* @site http://xjaphx.blogspot.com/
*/

#include <gtk/gtk.h>

/* declare a message box widget */
GtkWidget *msg_box;

/* construct a message box dialog */
void
MessageBox( GtkMessageType mType, GtkButtonsType bType, const gchar *title,
const gchar *msg, const gchar *details )
{
/* message box response code */
int res;
/* create a message box dialog */
msg_box = gtk_message_dialog_new( NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
mType, bType, msg );
/* set message box title */
gtk_window_set_title( GTK_WINDOW( msg_box ), title );
/* set detail text */
gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( msg_box ), details );
/* run the message box dialog */
res = gtk_dialog_run( GTK_DIALOG( msg_box ) );
/* check for dialog response and handle */
if( res == GTK_RESPONSE_OK )
gtk_widget_destroy( msg_box );
}

void
btn_info_clicked( GtkButton *btn, gpointer data )
{
MessageBox( GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "[JaPh] Dialog: INFO" ,
"GtkMessageDialog: Info", "This is an example of INFO Dialog" );
}
void
btn_warn_clicked( GtkButton *btn, gpointer data )
{
MessageBox( GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "[JaPh] Dialog: WARNING",
"GtkMessageDialog: Warning", "This is an example of WARNING Dialog" );
}
void
btn_ques_clicked( GtkButton *btn, gpointer data )
{
MessageBox( GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK, "[JaPh] Dialog: QUESTION",
"GtkMessageDialog: Question", "This is an example of QUESTION Dialog" );
}
void
btn_erro_clicked( GtkButton *btn, gpointer data )
{
MessageBox( GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "[JaPh] Dialog: ERROR",
"GtkMessageDialog: Error", "This is an example of QUESTION Dialog" );
}

/* MAIN */
int
main( int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *btn_info, *btn_warn, *btn_ques, *btn_erro;
GtkWidget *btn_exit;

gtk_init( &argc, &argv );
/* construct main window */
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title( GTK_WINDOW( window ), "[JaPh]Lesson 11: GtkMessageDialog" );
gtk_widget_set_size_request( window, 200, 180 );
/* create vbox layout */
vbox = gtk_vbox_new( TRUE, 5 );
/* create buttons */
btn_info = gtk_button_new_with_mnemonic( "Show _Info" );
btn_warn = gtk_button_new_with_mnemonic( "Show _Warning" );
btn_ques = gtk_button_new_with_mnemonic( "Show _Question" );
btn_erro = gtk_button_new_with_mnemonic( "Show _Error" );
btn_exit = gtk_button_new_with_mnemonic( "E_xit" );
/* pack buttons to vbox from TOP to BOTTOM */
gtk_box_pack_start( GTK_BOX(vbox), btn_info, TRUE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX(vbox), btn_warn, TRUE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX(vbox), btn_ques, TRUE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX(vbox), btn_erro, TRUE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX(vbox), btn_exit, TRUE, TRUE, 0 );
/* add layout widget to main window */
gtk_container_add( GTK_CONTAINER(window), vbox );
/* button signal */
g_signal_connect( GTK_BUTTON( btn_info ), "clicked",
G_CALLBACK( btn_info_clicked ), NULL );
g_signal_connect( GTK_BUTTON( btn_warn ), "clicked",
G_CALLBACK( btn_warn_clicked ), NULL );
g_signal_connect( GTK_BUTTON( btn_ques ), "clicked",
G_CALLBACK( btn_ques_clicked ), NULL );
g_signal_connect( GTK_BUTTON( btn_erro ), "clicked",
G_CALLBACK( btn_erro_clicked ), NULL );

g_signal_connect( GTK_BUTTON( btn_exit), "clicked",
G_CALLBACK( gtk_main_quit ), NULL );
/* window signal */
g_signal_connect( window, "destroy", G_CALLBACK( gtk_main_quit ), NULL );
/* show window & widgets */
gtk_widget_show_all( window );

/* run Gtk+ app */
gtk_main();
return 0;
}

Remember to keep your practice always, don't forget!

Have fun!@

Under Linux:


$ ./program `perl -e 'print "param"'`

Under Windows

\>perl.exe -e "exec 'program.exe','param'"

Have fun!@

By default, when you first launch Cygwin, your username is yet recognized, the warning message is shown like below:

Your group is currently "mkpasswd". This indicates that
the /etc/passwd (and possibly /etc/group) files should be rebuilt.
See the man pages for mkpasswd and mkgroup then, for example, run
mkpasswd -l [-d] > /etc/passwd
mkgroup -l [-d] > /etc/group
Note that the -d switch is necessary for domain users.

As the warning suggestions, run those above commands and your home user directory will be created, which is in : ~/cygwin/home/username

The created username is the same as the current Windows username.

Have fun!@

This is a freaking great joke.....I just couldn't help laughing this news...

Here a small quote:

It sounds like a joke. But, it's real and it's anything but a joke for Microsoft. Judge Leonard Davis, of the U.S. District Court for the Eastern District of Texas, has issued an injunction (PDF Link) that "prohibits Microsoft from selling or importing to the United States any Microsoft Word products that have the capability of opening .XML, .DOCX or DOCM files (XML files) containing custom XML."

Microsoft had been sued by i4i, a collaborative content solution and technology company. Its founder, Michel Vulpe, owned a patent covering a way of reading XML (Extended Markup Language) documents. XML is the basis of Microsoft's controversial Open XML document formats. The U.S. District Court for the Eastern District of Texas is infamous for supporting patent lawsuits and fast-tracking them. In intellectual property law circles, this Court has become known as "A Haven for Patent Pirates."


Reference:

http://blogs.computerworld.com/14532/microsoft_banned_from_selling_word

http://blogs.computerworld.com/14536/you_cant_buy_ms_word_i4i_xml_patent_ruling

http://blogs.computerworld.com/14537/microsoft_word_ban_its_time_to_banish_patent_lawyers

I've just found a new interesting page on cryptography and reversing.

It's called: +Ma's Reversing
Seem to be very interesting. I searched and looked up a place for sign up.
Well, it's well-said at INTRO, I have to solve the riddle to gain access to the site.
Read everything...then I wonder password is ....
=> Firefox, fire up View Source, I saw lines of comments in between. Wow, this is what mentioned in the last message line, "read between the lines".
Hum...so password is unsual. Because I have to solve a ciphered-text to gain password.

As in the comment, you can see that message:
<!-- MAL TIRRUEZF CR MAL RKZYIOL EX MAL OIY UAE RICF "MAL ACWALRM -->

<!-- DYEUPLFWL CR ME DYEU MAIM UL IZL RKZZEKYFLF GH OHRMLZH" -->

Interesting! So, how can we decode this message?
First, I thought of Caesar, the most popular one; however, failed.
I re-read the instructions carefully...It said to read his lesson-01.
Download the file, I read => got the idea menari.
Follow the idea w/ the hint "the message is written in English" ... I solved the riddle and gained access to the site.
Wow! This is so fun and interesting....
If you don't know this site, then you'd better try out.

Have fun!@

I've spent the whole night troubling w/ setting environments for exploit...but still not workingnangih.
Bang...at least I've gained something on my way...

Like Windows, Linux also provides modules for creating static library.

1. What is static library?
[A] It's a library that contains a list of API for a certain work, or to do something specifically that is pre-compiled and you don't have to recompile it again. If you know more about Linux, then you may know that a static library simply is just a compilation or a package of object code.
[*] Static library under Linux has extension ".a", while it is ".lib" in Windows.

2. What is the purpose of static library?
[A] As far as I know, firstly, since it's a library, it certainly gives APIs for convenient programming. It's already precompiled, so it costs less time to compile and load APIs than other types of libraries. Additionally, in case the author of the library wants to hide the actual source code.

3. When should I use static library?
[A] Well, you can use it any time you want. However, nowadays, Linux-ers don't prefer static library due to the faster computers and compilers.

Let's create our first Linux static library. Certainly, the programming language in use is C, or you can use C++.

I - Creating the library
1. Prepare:
[+] You need to create 2 files: one is the header, one is the source.
[+] Naming: all Linux libraries start with prefix "lib"

--[libhello.h]--


/*
* @author [JaPh]
* @date 14 August, 2009
* @file libhello.h
* @license freeware
*/

void hello( );

--[libhello.c]--

/*
* @author [JaPh]
* @date 14 August, 2009
* @file libhello.c
* @license freeware
*/

#include <stdio.h>

void hello( ) {
printf("[JaPh]Tutorial: Creating Linux Static Library\n"
"Message: Hello! This is a static library.\n");
}

2 - Compile the object code

[japh@localhost C]$ gcc -c libhello.c

3 - Create the library

[japh@localhost C]$ ar -cvsq libhello.a libhello.o
a - libhello.o

Finally, the file libhello.a created. This is our target static library

II - Use the library
The next thing we need to do is to test whether our library works or not.
Let's write a simple program to call the function hello() inside the library libhello.a

--[hello_main.c]--

/*
* @author [JaPh]
* @date 14 August, 2009
* @file hello_main.c
* @license freeware
*/

#include "libhello.h"

int main( ) {
hello( );
return 0;
}

Then compile:

[japh@localhost C]$ gcc -o hello hello_main.c -L/path/to/library -lhello

You need to specify the location where you put the file libhello.a
Since it's a standard under Linux, you don't have to specify -libhello, use -lhello instead.
Finally, run our program

[japh@localhost C]$ ./hello
[JaPh]Tutorial: Creating Linux Static Library
Message: Hello! This is a static library.

There you have your first Linux static library. Pretty simple and very handy
If you don't want to type again and again for those steps, I've written this tiny script for auto-work everything. You just need to put all 3 files above into the same directory, then run the script below. You can change things in the script for personally wants.

#!/bin/sh
echo "[1] Compiling Object Code"
gcc -Wall -c libhello.c

echo "[2] Creating library"
ar -cvsq libhello.a libhello.o

echo "[3] Compiling program"
gcc -o hello hello_main.c -L. -lhello

echo "[4] Running program"
./hello


Well, that's all I have for you in this topic.

Have fun!@

My friends wonder how to copy & paste from/to Putty under Linux.

Here the trick:

+ in putty screen, highlight the text you want to copy, move to text application, press middle-button of the mouse to paste it.
+ vice versa, highlight and copy the text you want to paste into Putty, then press the middle-button to paste into Putty.

Have fun!@

I have introduced about GtkVBox in the previous lesson; however, GtkHBox is basically the same as GtkVBox. The only difference is the horizontal arrangement of GtkHBox.
Reference GtkHBox

Things do the same.
So just try to mix GtkHBox and GtkVBox you can do a small application like this:Why not make it a practice?

Detail: an Gtk+ application, like a phone dial

When you done, you can check out my source below, it's pretty handy though...



/*
* @author [JaPh]
* @date August 12, 2009
* @file GtkHVBox_01.c
* @site http://xjaphx.blogspot.com/
*/

#include <gtk/gtk.h>
#include <string.h>

void
gtk_label_append_text( GtkLabel *label, char *s )
{
int len = strlen( gtk_label_get_text( label ));
gchar buf[128];
snprintf( buf, len + 2, "%s%s", gtk_label_get_text( label ), s );
gtk_label_set_text( label, buf );
}

void
btn1_clicked_event( GtkButton *btnN, GtkLabel *label )
{
gtk_label_append_text( label, "1");
}
void
btn2_clicked_event( GtkButton *btnN, GtkLabel *label )
{
gtk_label_append_text( label, "2");
}
void
btn3_clicked_event( GtkButton *btnN, GtkLabel *label )
{
gtk_label_append_text( label, "3");
}
void
btn4_clicked_event( GtkButton *btnN, GtkLabel *label )
{
gtk_label_append_text( label, "4");
}
void
btn5_clicked_event( GtkButton *btnN, GtkLabel *label )
{
gtk_label_append_text( label, "5");
}
void
btn6_clicked_event( GtkButton *btnN, GtkLabel *label )
{
gtk_label_append_text( label, "6");
}
void
btn7_clicked_event( GtkButton *btnN, GtkLabel *label )
{
gtk_label_append_text( label, "7");
}
void
btn8_clicked_event( GtkButton *btnN, GtkLabel *label )
{
gtk_label_append_text( label, "8");
}
void
btn9_clicked_event( GtkButton *btnN, GtkLabel *label )
{
gtk_label_append_text( label, "9");
}

void
btn_clear_clicked_event( GtkButton *btn_clear, GtkLabel *label )
{
gtk_label_set_text( label, " " );
}

int
main( int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *hbox1, *hbox2, *hbox3, *hbox4;
GtkWidget *btn1, *btn2, *btn3, *btn4,
*btn5, *btn6, *btn7, *btn8, *btn9;
GtkWidget *btn_clear, *btn_exit;

gtk_init( &argc, &argv );

/* window */
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title( GTK_WINDOW(window), "[JaPh]Lesson 10: GtkHBox & GtkVBox" );
gtk_widget_set_size_request( window, 300, 300 );

/* top level vbox */
vbox = gtk_vbox_new( TRUE, 0 ) ;

/* hbox1: btn1, btn2, btn3 */
hbox1 = gtk_hbox_new( TRUE, 0 );
btn1 = gtk_button_new_with_label("1");
btn2 = gtk_button_new_with_label("2");
btn3 = gtk_button_new_with_label("3");
gtk_box_pack_start( GTK_BOX( hbox1 ), btn1, TRUE, TRUE, 5 );
gtk_box_pack_start( GTK_BOX( hbox1 ), btn2, TRUE, TRUE, 5 );
gtk_box_pack_start( GTK_BOX( hbox1 ), btn3, TRUE, TRUE, 5 );

/* hbox2: btn4, btn5, btn6 */
hbox2 = gtk_hbox_new( TRUE, 0 );
btn4 = gtk_button_new_with_label("4");
btn5 = gtk_button_new_with_label("5");
btn6 = gtk_button_new_with_label("6");
gtk_box_pack_start( GTK_BOX( hbox2 ), btn4, TRUE, TRUE, 5 );
gtk_box_pack_start( GTK_BOX( hbox2 ), btn5, TRUE, TRUE, 5 );
gtk_box_pack_start( GTK_BOX( hbox2 ), btn6, TRUE, TRUE, 5 );

/* hbox3: btn7, btn8, btn9 */
hbox3 = gtk_hbox_new( TRUE, 0 );
btn7 = gtk_button_new_with_label("7");
btn8 = gtk_button_new_with_label("8");
btn9 = gtk_button_new_with_label("9");
gtk_box_pack_start( GTK_BOX( hbox3 ), btn7, TRUE, TRUE, 5 );
gtk_box_pack_start( GTK_BOX( hbox3 ), btn8, TRUE, TRUE, 5 );
gtk_box_pack_start( GTK_BOX( hbox3 ), btn9, TRUE, TRUE, 5 );

/* hbox4: btn_clear, btn_exit */
hbox4 = gtk_hbox_new( TRUE, 0 );
btn_clear = gtk_button_new_with_label("Clear");
btn_exit = gtk_button_new_with_label("Exit");
gtk_box_pack_start( GTK_BOX( hbox4 ), btn_clear, TRUE, TRUE, 5 );
gtk_box_pack_start( GTK_BOX( hbox4 ), btn_exit, TRUE, TRUE, 5 );

/* vbox: hbox1, hbox2, hbox3, hbox4 */
label = gtk_label_new("Click any number button");
gtk_box_pack_start( GTK_BOX( vbox ), label, TRUE, TRUE, 0 );
gtk_box_pack_start( GTK_BOX( vbox ), hbox1, TRUE, TRUE , 5 );
gtk_box_pack_start( GTK_BOX( vbox ), hbox2, TRUE, TRUE , 5 );
gtk_box_pack_start( GTK_BOX( vbox ), hbox3, TRUE, TRUE , 5 );
gtk_box_pack_start( GTK_BOX( vbox ), hbox4, TRUE, TRUE , 5 );

/* add to window */
gtk_container_add( GTK_CONTAINER( window ), vbox );

/* signal connect */
/* window */
g_signal_connect( window, "destroy",
G_CALLBACK( gtk_main_quit ), NULL );

/* btn1->9 */
g_signal_connect( GTK_BUTTON( btn1 ), "clicked",
G_CALLBACK( btn1_clicked_event ), GTK_LABEL( label ) );

g_signal_connect( GTK_BUTTON( btn2 ), "clicked",
G_CALLBACK( btn2_clicked_event ), GTK_LABEL( label ) );

g_signal_connect( GTK_BUTTON( btn3 ), "clicked",
G_CALLBACK( btn3_clicked_event ), GTK_LABEL( label ) );

g_signal_connect( GTK_BUTTON( btn4 ), "clicked",
G_CALLBACK( btn4_clicked_event ), GTK_LABEL( label ) );

g_signal_connect( GTK_BUTTON( btn5 ), "clicked",
G_CALLBACK( btn5_clicked_event ), GTK_LABEL( label ) );

g_signal_connect( GTK_BUTTON( btn6 ), "clicked",
G_CALLBACK( btn6_clicked_event ), GTK_LABEL( label ) );

g_signal_connect( GTK_BUTTON( btn7 ), "clicked",
G_CALLBACK( btn7_clicked_event ), GTK_LABEL( label ) );

g_signal_connect( GTK_BUTTON( btn8 ), "clicked",
G_CALLBACK( btn8_clicked_event ), GTK_LABEL( label ) );

g_signal_connect( GTK_BUTTON( btn9 ), "clicked",
G_CALLBACK( btn9_clicked_event ), GTK_LABEL( label ) );


/* btn_clear */
g_signal_connect( GTK_BUTTON( btn_clear ), "clicked",
G_CALLBACK( btn_clear_clicked_event ), GTK_LABEL( label ) );

/* btn_exit */
g_signal_connect( GTK_BUTTON(btn_exit), "clicked",
G_CALLBACK( gtk_main_quit ), NULL );

gtk_widget_show_all( window );

gtk_main();

return 0;
}

This is my little video guide through the wargame of SmashTheStack.Org

Wargame: SmashTheStack.Org | IO | Level 3
Creator: [JaPh]
Video: [ OGV | Length: 13.38 min | 30.5 MB | Super High Quality ]
Download: Rapidshare
Password: [japh]

Have fun!@

A note on x86 Registers

Intel x86's registers can be divided into several categories:

  • General-purpose registers
  • Segment registers
  • Program flow control registers
  • Other registers.
General-purpose registers include EAX, EBX, ECX, EDX, ESP EBP, ESI, and EDI. They are not all equal in their usage, and some instructions assign them special functionality. Segment registers are used to point to different seg-ments of process address space.Their functions are as follows: CS points to the beginning of a code segment; SS is a stack segment; DS, ES, FS, GS, and various other data segments, for example, the segment where static data is kept. Many processor instructions implicitly use one of these segment registers, so usually we will not need to mention them in our code. If you want to be more precise, instead of an address in memory these registers contain references to internal processor tables that are used to support virtual memory.

EIP: Extended Instruction Pointer. When you call a function, this pointer is saved on the stack for later use. When the function returns, this saved address is used to determine the location of the next executed instruction.

ESP: Extended Stack Pointer. This points to the current position on the stack and allows things to be added to and removed from the stack using push and pop operations or direct stack pointer manipulations.

EBP: Extended Base Pointer. This register usually stays the same throughout the execution of a function. It serves as a static point for referencing stack-based information such as variables and data in a function using offsets.This pointer usually points to the top of the stack for a function.

Reference from:
  • Buffer Overflow Attacks: Detect, Exploit, Prevent (by James C. Foster, Vitaly Osipov, Nish Bhalla, Niels Heinen)

Just several days, I've known that I need to learn more and had better study faster than I did. It's not time for rest or slowly gain, I have to make a jump forward science and technology; but it should be always a good jump. Well, not exactly always but a better frequency.
The proof is I was freaking slow to figure out [smashthestack] wargame level 4....shame on me as a Linux user. The second, level 0 in [overthewire-vortex] wargame took me such a long time to handle bytes received. It's been such a long time I haven't programmed network in perl. How shameful I am!
Thanks God for these events coming up, so that I know what levels of my current skills and abilities. Therefore, I have to train myself more and better.
IT'S A MUST !

This is my little video guide through the wargame of SmashTheStack.Org

Wargame: SmashTheStack.Org | IO | Level 2
Creator: [JaPh]
Video: [ OGV | Length: 12.26 min | 36 MB | Super High Quality ]
Download: Rapidshare
Password: [japh]


Have fun!@

SmashTheStack Wargame Video Guide Series
Creator: [JaPh]


Have you ever heard of SmashTheStack.Org ?
Yeah, they provide really nice wargames for practicing computer skills.
If you have any troubles, I provide this series as a little guide for you.

The IO Wargame

Level 1 - Guide
Level 2 - Guide
Level 3 - Guide
Level 4 - Guide
Level 5 - Guide

[ to be continued ... ]

Have fun!@