Author Topic: Factionwars teaches ASM (x86 Linux Netwide Assembler)  (Read 6248 times)

0 Members and 1 Guest are viewing this topic.

Offline RedBullAddicted

  • VIP
  • Sir
  • *
  • Posts: 519
  • Cookies: 189
    • View Profile
Factionwars teaches ASM (x86 Linux Netwide Assembler)
« on: October 18, 2013, 09:56:33 am »
Intro

Lately I decided that it would be awesome to know more about the assembly language. Factionwars, kind as he is, offered to help me learn it and began to hold a class for me. Later, he asked me if I can post it on evilzone so that others can get some out of it too. I dont just want to post the corresponding IRC logs but use the thread as some kind of a summary for myself. So.. enough about all that. Here it is :)

Recommended: http://en.wikibooks.org/wiki/X86_Assembly
I will update this post everytime Factionwars showed me something new :P

# - Lesson 1


0x01 Very basic ELF file layout

Quote
<Factionwars> What segments do you have in your nasm file?
<Factionwars> You have atleast one already
<Factionwars> Givining you a class here
<Factionwars> be active
<rba_work> yes :) .data and .text which has the _global _start and a _start: section. As far as I understood _start: is equal to a main function in c
<Factionwars> Nope
<rba_work> well.. I think I should go back to reading then
<rba_work> lol
<Factionwars> no faggot i am writing
<rba_work> ok :)
<Factionwars> All default elf files have _start as their entry point, c/c++ compiled elf files also have this, but there happens some prologue work for the main function to be runned smoothly.

Code: (asm) [Select]

; this is a comment .. lol
section .text                            ; defines the section where your program code is located
    global _start                       ; this is needed by the linker (ld)
 _start:                                   ; All default elf files have _start as their entry point
    ;do something here


0x02 General Purpose Registers (GPR)

Quote
<Factionwars> So the 32 bit general purpose registers are EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP,
<Factionwars> Where the last 2 are used for controlling the stack only
<Factionwars> We will later get on to that.
<Factionwars> Okay you have EAX
<Factionwars> EAX is a 32 bit register, as you know 32 bit wasn't always the standard so you also have 16 bit
<Factionwars> You can access the lower 16 bits of EAX by using AX
<Factionwars> This is the same for BX, CB, SI, DI, BP, SP

 
Image: http://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture
 

 
Quote
<Factionwars> AX can be divided in 2 halfs, the lower and the higher
<Factionwars> Try to connect words to everything
<Factionwars> so AX = AL + AH
<Factionwars> AX = ALOW + AHIGH
<Factionwars> :)
<Factionwars> So in order to write 0x000004 to EAX you could just do mov al, 0x04 (assuming that eax is zero already)
<Factionwars> or mov ah, 0x04 results in 0x00000400
<Factionwars> Because AH is the high half of AX

0x03 Linux Syscalls

Quote
<Factionwars> The way you have to look up the syscall number
<Factionwars> is
<Factionwars> vim /usr/include/asm/unistd_32.h
<Factionwars> then take the name and do a "man 2 SYSCALL" this will give you detailed information about the syscall
<Factionwars> In C form so your exactly know how the data should look like
<Factionwars> Be sure that in the man page the only required include is unistd.h
<Factionwars> Later on we will talk about using glibc functions in ASM

man 2 exit
Code: [Select]
_EXIT(2)                     Linux Programmer's Manual                     _EXIT(2)
 
NAME
       _exit, _Exit - terminate the calling process
 
SYNOPSIS
       #include <unistd.h>
 
       void _exit(int status);
 
       #include <stdlib.h>
 
       void _Exit(int status);
 
   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
 
       _Exit():
           _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L;
           or cc -std=c99
 
DESCRIPTION
       The function _exit() terminates the calling process "immediately".  Any open
       file descriptors belonging to the process are closed; any  children  of  the
       process are inherited by process 1, init, and the process's parent is sent a
       SIGCHLD signal.

0x04 Executing a syscall
 
Quote
<Factionwars> So a rule to remember, syscall functions as defined in /usr/include/asm/unistd_32.h get their arguments by using the general purpose registers, where the first GPR (general purpose register) EAX is used for the syscall number
<Factionwars> 0x80 means that you have prepared a syscall and that you want it executed.
<Factionwars> So
<Factionwars> Open up a shell
<Factionwars> create a asm file
<Factionwars> Write the first part, that consist of the basic .text global _start _start (with spaces ofc)
 
<Factionwars> What do you know about the logical gates OR, AND, XOR,
<Factionwars> be quick
<Factionwars> Do you know what XOR does
<Factionwars> OR is one of both or both
<Factionwars> the X in XOR is execlusive
<Factionwars> That means One of both but not both
<Factionwars> In other words XOR 1, 1 == 0 XOR 1,0 == 1 XOR 0,1 == 1 XOR 0,0 == 0
<Factionwars> This is quite handy in assembly to zero out a register. Because XOR EAX, EAX is always zero.
 
<Factionwars> Start your asm file with putting some bogus into EAX, for example 0x1337.
<Factionwars> Then you want to do the syscall exit
<Factionwars> You know the EAX register is filled with something and you want it to zero in order to but 1 in the lower half of AX wich is the lower half of EAX.
<Factionwars> So you XOR eax by eax
<Factionwars> Because what eax is, it will always be or both true or both false thus always returning 0
<Factionwars> Then you set up your exit call by putting 0x01 in eax. But i want you to put it in the lower half of AX
<Factionwars> Then we want to give the return value of 1
<Factionwars> First we zero out the EBX register by xorring it with hiself. Then we INC ebx :)  thus resultin in 1

Code: (asm) [Select]
section .text
            global _start
 
_start:
            mov eax, 0x1337        ; Fill EAX with bogus data
            xor eax, eax                ; Set EAX to 0
 
            mov al, 0x01               ; Fill the lower 8 Bit of AX with 1
 
            xor ebx, ebx                ; Set EBX to 0
            inc ebx                        ; Increment EBX
 
            int 0x80                       ; call the Kernel

0x05 Compiling, linking and debugging
 
Quote
<Factionwars> great, we need though be sure that you are compiling everything 32 bit style. 
<Factionwars> in nasm: nasm -f elf32 FILE

Code: [Select]
debian nasm # ls
lesson1.asm
debian nasm # nasm –f elf32 lesson1.asm
debian nasm # ls
lesson1.asm lesson1.o

Quote
<Factionwars> then to link it to a ELF file: ld ass.o -o ass -m elf_i386
<Factionwars> I prefer to save that to a bash script
<Factionwars> for easy reference

Code: [Select]
debian nasm # ld lesson1.o -o lesson1 -m elf_i386
debian nasm # ls
lesson1 lesson1.asm lesson1.o

Quote
<Factionwars> you can check the return value with "echo $?" in bash

Code: [Select]
debian nasm # ./lesson1 | echo $?
1

Quote
<Factionwars> great
<Factionwars> Do you have gdb installed?
<Factionwars> then write : set disassembly-flavor intel  to /etc/gdb/gdbinit 
<Factionwars> That is a gdb command but because you don't want to write it everytime you will put it in there
<Factionwars> Great now open it up with "gdb filename"y
<Factionwars> And try to run it with run or just r

Code: [Select]
debian nasm # gdb lesson1

(gdb) run
Starting program: /rba/nasm/lesson1
[Inferior 1 (process 3091) exited with code 01]

0x06 Disassembling and breakpoints
 
Quote
<Factionwars> Now it just executes 
<Factionwars> But we want to see what is happening
<Factionwars> So we will add a breakpoint on _start
<Factionwars> Your entry point
<Factionwars> So "break _start"
<Factionwars> You can delete breakpoints with d/delete
<Factionwars> Now run it again

Code: [Select]
(gdb) break _start
Breakpoint 1 at 0x8048060
(gdb) run
Starting program: /rba/nasm/lesson1
 
Breakpoint 1, 0x08048060 in _start ()

Quote
<Factionwars> Now the program has loaded everything in memory and you can analyze all the things that happen.
<Factionwars> Try out some commands
<Factionwars> "disas", "info registers", "s/step", "n/next"
<Factionwars> Try to visualize what happens
<Factionwars> By doing "disas" look at the registers, step, disas, look at the registers, step, disas
<Factionwars> you will get the idea
<Factionwars> Do you like  how awesome it is that asm just does what you tell it?
<Factionwars> When you do a "xor" there is no code who runs the xor :)
<Factionwars> It's all up to you to instruct the processor

Code: [Select]
(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) break _start
Breakpoint 3 at 0x8048060
(gdb) run
Starting program: /rba/nasm/lesson1
 
Breakpoint 3, 0x08048060 in _start ()
(gdb) disas
Dump of assembler code for function _start:
=> 0x08048060 <+0>:     mov    eax,0x1337
   0x08048065 <+5>:     xor    eax,eax
   0x08048067 <+7>:     mov    ax,0x1
   0x0804806b <+11>:    xor    ebx,ebx
   0x0804806d <+13>:    inc    ebx
   0x0804806e <+14>:    int    0x80
End of assembler dump.
(gdb) into registers
Undefined command: "into".  Try "help".
(gdb) info registers
eax            0x0      0
ecx            0x0      0
edx            0x0      0
ebx            0x0      0
esp            0xbffffcf0       0xbffffcf0
ebp            0x0      0x0
esi            0x0      0
edi            0x0      0
eip            0x8048060        0x8048060 <_start>
eflags         0x296    [ PF AF SF IF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x0      0



# - Lesson 2 - Syscall 11 execve

0x01 the .data section

Quote
<Factionwars> First write the usual skeleton, until you reach the _start
<Factionwars> rba_work, before the text section add a data section
<Factionwars> section .data
<Factionwars> The data section is used to store Global and Static variables.

So our very basic ELF file layout now looks like this:

Code: (asm) [Select]
section .data
    ; initialized data

section .text
    global _start

_start:
    ; do something here

0x02 the dX instruction

Quote
<Factionwars> rba_work, in nasm you have a instruction called "dX" where d stands for define and the X is the data type. So in order to store a string we can use db == define byte and then enter a string or sequence of bytes.
<Factionwars> Let's define /bin/bash
<Factionwars> It's very easy, just input db "/bin/bash"
<rba_work> ok.. thats a var containing the string "/bin/bash"?
<Factionwars> It just puts the bytes right there in the data segment
<Factionwars> It's not a variable and it's not managed
<Factionwars> But
<Factionwars> If you have a little experience with programming you might know that in order to make it a valid string you will have to end a string with a null byte
<Factionwars> Can you do that ? :)
<Factionwars> hint: ", XXX
<rba_work> uh.. I have no clue.. lol. db, "$" .. I think I have seen that somewhere
<Factionwars> What is a null byte?
<rba_work> 0x00?
<Factionwars> jep
<rba_work> db "/bin/bash/, 0x00 ?
<Factionwars> So what does the string needs ?
<Factionwars> exactly :D
<Factionwars> Now we need a way to reference it
<Factionwars> That is where nasm is handy in comparison with raw assembly
<Factionwars> Nasm uses labels, just like _start: or any other label, nasm handles all the low level location troubles and headaches for you.
<Factionwars> so in order to reference your byte sequence you can add a label like : "bashString: db "/bin/bash", 0x00"

Code: (asm) [Select]
section .data
    bashString: db "/bin/bash", 0x00        ; define a sequence of bytes referenced by bashString
section .text
    global _start

_start:
    ; do something here

0x03 sys_execve syscall

Quote
<Factionwars> Can you think of any syscall we could use to execute /bin/bash?
<rba_work> you mentioned it earlier syscall 11 sys_execve
<rba_work> :P
<Factionwars> xD
<Factionwars> Now go ahead and man it and tell me what is does to your process
<Factionwars> 1 sentece
<Factionwars> sentence
<rba_work> it executes what I define in EBX, ECX is used for the commandline args?? and I have no clue what that means: char *const envp[]
<Factionwars> That does not answer my question :)
<Factionwars> "what it does to your process"

Can you answer the question?

Quote
<rba_work> execve() does not return on success, and the text, data, bss, and stack of the calling process are overwritten by that of the program loaded.
<Factionwars> maybe use man execve instead of man 2 execve
<Factionwars> You don't even need to read more than a paragraph from man execve
<Factionwars> rba_work,
<Factionwars> If you for once say what i want.. because i have a key clue laying around here :P
<Factionwars> I am going to do the next lessons without access to port 80 for you sir
<Factionwars> Gonna whip him, with this dragon thing from runescape. Where the graphics are so fucking worse that it hurts your eyes while it hurts your butt.
<rba_work> sorry.. the phone again. I throw it out of the window now
<rba_work> ok.. the programm loaded by execve overwrittes the stuff I defined in the calling process?
<Factionwars> What does the sentence say>?
<Factionwars> You can ask questions
<Factionwars> If you don't know what something means
<Factionwars> Or that or you give a right answer :P
<Factionwars> up to you :P
<rba_work> ok :P tbh I have no clue how to answer that question. My process to start the bash disappears after I loaded bash?
<Factionwars> Do you know what "the current process image" means?
<rba_work> memory image?
<rba_work> no, I guess.. lol
<Factionwars> When you assemble your file everything is written in segments, wich are the same as sections as you know it. When you launch a process the whole file is copied directly into memory. This resulting in having the perfect memory layout for your process. So your heap, data, bss, text etc. sections are written to the executable file and when launched copied into memory in your private memory space giving you a process image.
<Factionwars> Try out the linux app "readelf" you can do readelf --all executable or readelf --sections executable

Code: [Select]
debian nasm # readelf --all lesson1
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:               0x8048060
  Start of program headers:          52 (bytes into file)
  Start of section headers:          148 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         1
  Size of section headers:           40 (bytes)
  Number of section headers:         5
  Section header string table index: 2

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        08048060 000060 000010 00  AX  0   0 16
  [ 2] .shstrtab         STRTAB          00000000 000070 000021 00      0   0  1
  [ 3] .symtab           SYMTAB          00000000 00015c 000080 10      4   4  4
  [ 4] .strtab           STRTAB          00000000 0001dc 00002c 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x08048000 0x08048000 0x00070 0x00070 R E 0x1000

 Section to Segment mapping:
  Segment Sections...
   00     .text

There is no dynamic section in this file.

There are no relocations in this file.

The decoding of unwind sections for machine type Intel 80386 is not currently supported.

Symbol table '.symtab' contains 8 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 08048060     0 SECTION LOCAL  DEFAULT    1
     2: 00000000     0 FILE    LOCAL  DEFAULT  ABS lesson1.asm
     3: 00000000     0 FILE    LOCAL  DEFAULT  ABS
     4: 08048060     0 NOTYPE  GLOBAL DEFAULT    1 _start
     5: 08049070     0 NOTYPE  GLOBAL DEFAULT    1 __bss_start
     6: 08049070     0 NOTYPE  GLOBAL DEFAULT    1 _edata
     7: 08049070     0 NOTYPE  GLOBAL DEFAULT    1 _end

No version information found in this file.

Quote
<Factionwars> When you read the sections you can for example see that the .text section has AX flag. Where X means that you are allowed to execute code there :)
<rba_work> ok.. I can see that
<Factionwars> So what do you think that execve's replacing the memory image means in noob slang
<rba_work> the new process is copied in the location where I am allowed to execute?
<Factionwars> Almost
<Factionwars> Note some parts of my speech
<Factionwars> When you launch a process the whole file is copied directly into memory
<Factionwars> This resulting in having the perfect memory layout for your process.  == Process image
<Factionwars> We are almost there :)
<rba_work> ok.. so bash get copied into the location where my .text has been
<Factionwars> I am going to note parts of the note some parts of my speech part xD
<Factionwars> the whole file is copied
<Factionwars> rba_work, you are so close
<rba_work>  thee locations in memory where my "lesson2" programm was stored gets overwritten
<Factionwars> yay
<rba_work> because I copy the sections from the "bash" into it
<Factionwars> No not only the sections but everything

Quote
<Factionwars> So question, you can answer by analyzing the way i ask it but i ask for a little honesty if you are not sure.
<Factionwars> So the next*
<Factionwars> Do you need to do an exit call after you do a successfull execve call in order to make everything close down smoothly
<rba_work> I would assume no. Because after I executed the syscall my programm is gone anyways?
<rba_work> or my process
<Factionwars> :D
<Factionwars> Now write down or take in mind the arguments for execve, you can write them down on a piece of paper and add notes and make things clear for yourself.
<rba_work> I will try it :)
<Factionwars> I will ofcourse help you :P

Code: (c) [Select]
int execve(const char *filename, char *const argv[], char *const envp[]);
# First argument is a pointer to the file you want to execute
# Second argument is a array of pointers to command line arguments you want to pass
# third argument is a array of pointers of key, value pairs passed as enviroment to the new programm

Quote
<Factionwars> the char *const envp[] can be zero
<Factionwars> rba_work, do you know what char * loll means?
<Factionwars> Well, rba_work :D
<rba_work> yes.. thats a pointer to loll. It only stores the memory location of loll and not its content
<Factionwars> Jep :)
<Factionwars> And a label in nasm is the exact same
<rba_work> I made an intro to c some month ago.. lol
<rba_work> ok
<Factionwars> When you use it nasm replaces it with the adress
<Factionwars> Just like precompiler variables in c
<Factionwars> preproccessor*
<rba_work> ah.. I see.. so when I move bashlabel to EBX or something like that it does not store the string only the location where it is located?
<Xires> Factionwars; just an FYI, preprocessor variables do not replace the name w/ address
<Xires> preprocessor replaces the name with the defined content..kinda like running an sed script on the code real quick...find DEFINED_NAME, replace with DEFINED_VAL
<Factionwars> No but labels hold an adress in nasm and in c it holds the value defined
<Factionwars> There is no variable in nasm other than the adress
<Factionwars> That's what i am pointing at
<Factionwars> anyway
<Factionwars> rba_work,
<rba_work> yes
<Xires> I understand..just trying to make sure the terminology is correct with regard to C
<Factionwars> Yep :)
<Factionwars> rba_work, yes when you do mov ebx, _start. ebx will hold the location of _start.
<Factionwars> Because on this level there is no such thing as a string variable
<Factionwars> The only thing you have is a begin adress and a 0x00 byte.
<Factionwars> That is the definition of a string on this level
<Factionwars> Later on when you are using c you will encounter the same.
<rba_work> ok.. I think I understood it. For the arguments I need to pass to execv. the first is pretty clear.. here I need to provide my label. Don't think I need the second and third in this case, right?
<Xires> rba_work; execv() != execve()
<Factionwars> rba_work, No but you need to pass them in a correct format. So if you want to give zero arguments, make sure the function will not read arbitary data.
<Xires> <Factionwars> The only thing you have is a begin adress and a 0x00 byte.
<Xires> ^ hint
<Xires> Factionwars; you're doin' a fairly awesome job
<Xires> I'm going to go plot against an evil corporation now
<Xires> have fun
<Factionwars> Ah well, always try to write tutorials and stuff. But i think this form is a pretty good one.,
<Factionwars> Good luck :P
<Xires> rba_work; good luck..you're doin' well so far
<rba_work> its difficult tbh. But all first steps are difficult.. lol. Thx :)
<Factionwars> Allright
<Factionwars> Let's get blazing
<Factionwars> First EAX
<rba_work> mov EAX, 0x0b
<Factionwars> congrats
<Factionwars> :D
<Factionwars> btw
<Factionwars> Something i use : python2, and then in the cli app "print 0x0b" for example
<Factionwars> or i = 123123
<Factionwars> i.encode("hex")
<rba_work> I use hex(11) :)
<Factionwars> nice :)
<Factionwars> next on, ebx
<rba_work> I have no clue but I would try mov ebx, 0x00 or xor ebx, ebx ?
<Factionwars>  int execve(const char *filename, char *const argv[],
<Factionwars>                   char *const envp[]);
<Factionwars> So the first argument is?
<rba_work> the script name?
<Factionwars> const char *filename
<rba_work> ah.. I see.. lol. Totally overlooked it.. lol
<Factionwars> And as you know the first argument is passed on by ebx
<rba_work> mov ebx, bashlabelö
<rba_work> ?
<Factionwars> without the ö xD
<rba_work> :)
[<Factionwars> As you might know in c the command line arguments are put in argv
<Factionwars> And it's a pointer
<Factionwars> A pointer array.
<Factionwars> An array of char pointers to be exact
<Factionwars> the pointer itself has to be valid, but the array has to be zero
<Factionwars> So if i have your attention we can do something awesome
<rba_work> sure :) when you say awesome you mean difficult to understand, right? lol
<Factionwars> no awesome
<rba_work> ok :P

0x04 A short intro to the stack


Quote
<Factionwars> LIFO
<Factionwars> Did you ever work in a supermarket?
<Factionwars> In a supermarket you have FIFO, first in first out. This results when you take a product from a shelve you take the oldest one. And the shopkeeper puts in the newest at the back so the oldest get's taken out. When you would implement a LIFO order in a supermarket you will find expired products at the back of the shelve. Well, we want that:P
<Factionwars> Next on
<Factionwars> The stack
<Factionwars> The stack is a LIFO structure
<Factionwars> The stack can be controlled via different ways.
<Factionwars> Let's first tell what the stack is used for,
<Factionwars> The stack is used for, local variables, arguments(in higher languages like C), and a functions return adress ( we will cover that later).
<Factionwars> The registers are only 32 bits wide, and when you are processing big strings, arrays or anything else the stack is the perfect place. Though when things tend to get really really big or you need a global/static variable declared at runtime you will use the heap (later on we will talk)
<Factionwars> I am going to sound like vivek.
<Factionwars> So because we need to give execve a pointer to an empty array we will use the stack
<Factionwars> The basic stack usage is through POP and PUSH
<Factionwars> push ebx  pushes the value of ebx on the stack
<Factionwars> pop ebx pushes the latest value on the stack into ebx
<Factionwars> push ebx - push ecx - pop ebx
<Factionwars> Will do ?
<Factionwars> Will result in?*

Try to answer it before you go on reading :)

Quote
<rba_work> I push ebx and ecx on the stack. pop ebx updates ebx on the stack with the last value I assigned to it?
<Factionwars> resulting in ebx having the same value as?
<rba_work> ecx? cause that was the last I pushed on the stack? LIFO?
<Factionwars> yes :)
<Factionwars> So we want to create an pointer pointing at a bunch of zero's
<Factionwars> Do you have any clue where to start?
<Factionwars> you can hit the jackpot with this question
<Factionwars> It's a hard one

And again.. can you answer the question?

Quote
<rba_work> I have no clue but I try to answer it. eax holds the syscall ebx the label which is a pointer to the defined string. so I would xor ecx, ecx to make it empty. than I would push ecx and pop a couple of other registers. Tbh that sounds wrong.. lol
<rba_work> ok.. I have no clue
<Factionwars> You went in to the good direction.
<Factionwars> In order to make a empty array we can xor ecx to zero, then push it onto the stack. And then magic

0x05 the esp register

Quote
<Factionwars> A register you have not yet used but now you will : esp/sp the STACK POINTERRRRR
<Factionwars> The ESP register holds the value of the current top of the stack
<Factionwars> In other words, when i push "HELLO I AM A TOTAL FAGGOT" to the stack and i put ESP into EAX. EAX will then point to my string :D
<Factionwars> Do you understand any of that?
<rba_work> I get a slight idea. after I pushed the zeroed ecx to the stack I could mov ecx, esp and mov edx, esp?
<Factionwars> :)
<Factionwars> And then when you push other things the value of esp would change but not the value of ecx :P
<Factionwars> Though i hope you can understand that when you go popping you will pop off your pushed zero variable :)
<rba_work> if I do xor ecx, ecx then push ecx and pop ecx. ecx would not change.. right?
<rba_work> I guess I need to re-read that again :)
<Factionwars> Nope
<Factionwars> Well,
<Factionwars> I think it's good to just get this example going and the go on gdb
<rba_work> ok :P I will re-read it in a quite hour at home and come back to you if it is still unclear
<Factionwars> Sometime you just have to do it
<Factionwars> And see how it really works
<Factionwars> You can't really imagine how a car works when you never visualized one :P
<rba_work> thats true and a good point :)
<rba_work> ok.. I guess I have it so far.. sec

Code: (asm) [Select]
section .data
        bashstring:  db "/bin/bash", 0x00

section .text
        global _start

_start:
        mov eax, 0x0b           ; prepare the execve syscall
        mov ebx, bashstring     ; first argument is a pointer to the script that should be executed
        xor ecx, ecx            ; zero out ecx
        push ecx                ; push ecx on the stack
        mov ecx, esp            ; copy the stack pointer into ecx to have a pointer for argv
        mov edx, esp            ; copy the stack pointer into edx to have a pointer for envp
        int 0x80                ; execute it


Quote
[15:41:43] <Factionwars> Does it work ? :P
[15:41:53] <rba_work> I will try it :)
[15:43:33] <rba_work> It works.. ;)
[15:43:43] <Factionwars> Congrats :D
[15:44:05] <Factionwars> Be proud of yourself
[15:44:17] <Factionwars> You didn't watch a corny youtube video and wrote the same thing he did

0x06 visualisation

Code: [Select]
root@DebDev86:/home/rba/asm# ls
lesson2.asm
root@DebDev86:/home/rba/asm# nasm -f elf32 lesson2.asm
root@DebDev86:/home/rba/asm# ld lesson2.o -o lesson2 -m elf_i386
root@DebDev86:/home/rba/asm# cat /etc/gdb/gdbinit
# System-wide GDB initialization file.
set disassembly-flavor intel
root@DebDev86:/home/rba/asm# ps aux | grep bash
root     17421  0.0  0.1   5224  2528 pts/0    Ss   10:33   0:00 -bash
rba      17466  0.0  0.1   5248  2576 pts/0    S    10:33   0:00 bash
root     17536  0.0  0.0   4704  1856 pts/0    S    10:40   0:00 bash
root     17582  0.0  0.0   3548   792 pts/0    S+   10:49   0:00 grep bash
root@DebDev86:/home/rba/asm# ./lesson2
root@DebDev86:/home/rba/asm# ps aux | grep bash
root     17421  0.0  0.1   5224  2528 pts/0    Ss   10:33   0:00 -bash
rba      17466  0.0  0.1   5248  2576 pts/0    S    10:33   0:00 bash
root     17536  0.0  0.0   4704  1860 pts/0    S    10:40   0:00 bash
root     17583  0.0  0.0   3144  1636 pts/0    S    10:50   0:00 [bash]
root     17585  0.0  0.0   2020   524 pts/0    S+   10:50   0:00 grep bash
root@DebDev86:/home/rba/asm# exit
exit
root@DebDev86:/home/rba/asm# gdb lesson2
...
(gdb) break _start
Breakpoint 1 at 0x8048080
(gdb) run
Starting program: /home/rba/asm/lesson2

Breakpoint 1, 0x08048080 in _start ()
(gdb) disas
Dump of assembler code for function _start:
=> 0x08048080 <+0>: mov    eax,0xb
   0x08048085 <+5>: mov    ebx,0x8049094
   0x0804808a <+10>:  xor    ecx,ecx
   0x0804808c <+12>:  push   ecx
   0x0804808d <+13>:  mov    ecx,esp
   0x0804808f <+15>:  mov    edx,esp
   0x08048091 <+17>:  int    0x80
End of assembler dump.
(gdb) info registers
eax            0x0  0
ecx            0x0  0
edx            0x0  0
ebx            0x0  0
esp            0xbffff840 0xbffff840
ebp            0x0  0x0
esi            0x0  0
edi            0x0  0
eip            0x8048080  0x8048080 <_start>
eflags         0x292  [ AF SF IF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x0  0
(gdb) run
Single stepping until exit from function _start,
which has no line number information.
process 17588 is executing new program: /bin/bash

Breakpoint 1, 0x08064678 in _start ()
(gdb) disas
Dump of assembler code for function _start:
=> 0x08064678 <+0>: xor    ebp,ebp
   0x0806467a <+2>: pop    esi
   0x0806467b <+3>: mov    ecx,esp
   0x0806467d <+5>: and    esp,0xfffffff0
   0x08064680 <+8>: push   eax
   0x08064681 <+9>: push   esp
   0x08064682 <+10>:  push   edx
   0x08064683 <+11>:  push   0x80f5f50
   0x08064688 <+16>:  push   0x80f5f60
   0x0806468d <+21>:  push   ecx
   0x0806468e <+22>:  push   esi
   0x0806468f <+23>:  push   0x8062dc0
   0x08064694 <+28>:  call   0x80626c0 <__libc_start_main@plt>
   0x08064699 <+33>:  hlt   
   0x0806469a <+34>:  nop
   0x0806469b <+35>:  nop
   0x0806469c <+36>:  nop
   0x0806469d <+37>:  nop
   0x0806469e <+38>:  nop
   0x0806469f <+39>:  nop
   0x080646a0 <+40>:  mov    eax,0x812e777
   0x080646a5 <+45>:  sub    eax,0x812e774
...
 
End of assembler dump.
(gdb) info registers
eax            0xb7fff908 -1207961336
ecx            0xb7ffbd3b -1207976645
edx            0xb7ff0590 -1208023664
ebx            0xb7ffeff4 -1207963660
esp            0xbfffff20 0xbfffff20
ebp            0x0  0x0
esi            0xbfffff28 -1073742040
edi            0x8064678  134628984
eip            0x8064678  0x8064678 <_start>
eflags         0x286  [ PF SF IF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

After the process executed the execve syscall our lesson2 process gets overwritten with the bash process
process 17588 is executing new program: /bin/bash

Bonus question :)

Quote
<Xires> rba_work; what's significant about the .text section?
<Factionwars> Xires, we are not totally there :P
<Xires> K
<Factionwars> Not about section protection and everything
<Xires> K
<Factionwars> But rba_work  try to answer it :)

After reading the first lesson you should be able to answer Xires question the way I did

Quote
<rba_work> its the section where my actual program code goes that is executed?
<Factionwars> That will do :P
<rba_work> puh.. lol. The pressure.. lol


# - Lesson 3 - disassemble a c program

0x01 Intro

sample Program in c

Code: (c) [Select]
#include <stdio.h>
     
//A local uninitalized and initialized variable.
int global_uninitalized;
int global_initialized = 1;
     
int main(int argc, char * argv[])
{
    //A local variable
    int local = 150;
    //If argc < 2 then please give arguments:P
    if(argc < 2)
        printf("Please give me a integer");
    //atoi == ascii to integer, it parses a ascii string and gives back the int
    //, so 1 in ascii is 1 in real integer and not the number of the ascii value itself.
    local += atoi(argv[1]);
     
    //printf the addition, where the first parameter is parsed and %d is a string format argument
    //Wich equals "decimal", so it expects a decimal to be placed there as second parameter
     
    printf("The addition of 150 + %s = %d", argv[1], local);
     
    return 0;
}

Quote
<Factionwars> soso
<Factionwars> Well if you understand this code
<Factionwars> Let's get to the more awesome parts of asm
<Factionwars> gcc -m32 inputfile -o outputfile
<Factionwars> Run it and see if it does what you think it does

Code: [Select]
root@DebDev86:/home/rba/asm# gcc -m32 lesson3.c -o lesson3
root@DebDev86:/home/rba/asm# ./lesson3 10
The addition of 150 + 10 = 160

0x02 define hook-stop in gdb

Quote
<Factionwars> Load it in gdb
<Factionwars> and break the _start
<rba_work> ok
<Factionwars> you afk or something
<rba_work> no.. I did it :)
<rba_work> have it open in gdb and set a breakpoint at _start.
<Factionwars> took you so long? :P
<Factionwars> Allright
<rba_work> I went ahead and run a disas and understood nothing.. lol.
<Factionwars> That's not what i instructed
<rba_work> I know.. I am sorry :(
<Factionwars> Allright
<Factionwars> type in "k" to kill it
<Factionwars> sec
<Factionwars> allright rba_work
<Factionwars> Now i am going to introduce you to something nice of gdb
<Factionwars> "define hook-stop"
<Factionwars> That allows you to set commands on everytime you step :)
<Factionwars> So type in disas *enter* end *enter*
<Factionwars> after the define hook-stop ofc
<Factionwars> sorry :P
<rba_work> ah.. nice.. I have that

Code: [Select]
root@DebDev86:/home/rba/asm# gdb ./lesson3
...
(gdb) break _start
Breakpoint 1 at 0x8048360
(gdb) define hook-stop
Type commands for definition of "hook-stop".
End with a line saying just "end".
>disassemble
>end
(gdb) run 10
Starting program: /home/rba/asm/lesson3 10
Dump of assembler code for function main:
   0x0804844c <+0>:    push   ebp
   0x0804844d <+1>:    mov    ebp,esp
=> 0x0804844f <+3>:    and    esp,0xfffffff0
   0x08048452 <+6>:    sub    esp,0x20
   0x08048455 <+9>:    mov    DWORD PTR [esp+0x1c],0x96
   0x0804845d <+17>:    cmp    DWORD PTR [ebp+0x8],0x1
   0x08048461 <+21>:    jg     0x804846f <main+35>
   0x08048463 <+23>:    mov    DWORD PTR [esp],0x8048540
   0x0804846a <+30>:    call   0x8048320 <printf@plt>
   0x0804846f <+35>:    mov    eax,DWORD PTR [ebp+0xc]
   0x08048472 <+38>:    add    eax,0x4
   0x08048475 <+41>:    mov    eax,DWORD PTR [eax]
   0x08048477 <+43>:    mov    DWORD PTR [esp],eax
   0x0804847a <+46>:    call   0x8048350 <atoi@plt>
   0x0804847f <+51>:    add    DWORD PTR [esp+0x1c],eax
   0x08048483 <+55>:    mov    eax,DWORD PTR [ebp+0xc]
   0x08048486 <+58>:    add    eax,0x4
   0x08048489 <+61>:    mov    eax,DWORD PTR [eax]
   0x0804848b <+63>:    mov    edx,DWORD PTR [esp+0x1c]
   0x0804848f <+67>:    mov    DWORD PTR [esp+0x8],edx
   0x08048493 <+71>:    mov    DWORD PTR [esp+0x4],eax
   0x08048497 <+75>:    mov    DWORD PTR [esp],0x8048559
   0x0804849e <+82>:    call   0x8048320 <printf@plt>
   0x080484a3 <+87>:    mov    eax,0x0
   0x080484a8 <+92>:    leave 
   0x080484a9 <+93>:    ret   
End of assembler dump.


Breakpoint 1, 0x08048360 in _start ()

0x03 basic unix function prologue

Quote
<Factionwars> delete your breakpoints
<Factionwars> "D"
<Factionwars> lowecase that is
<Factionwars> break on main
<Factionwars> run it
<Factionwars> and what do you see
<Factionwars> What is something noticable
<rba_work> nice.. it breaks on main and automatically executes the disas command :) esp gets loaded with the memory location of main?
<Factionwars> There is 1 thing you should be able to notice pretty easily
<Factionwars> You set a breakpoint on main
<Factionwars> And where is your EIP?
<Factionwars> You don't need to enter any commands
<Factionwars> just look :P
<Factionwars> EIP == [e]instruction pointer
<rba_work>  here? 0x0804843f <+3>:     and    esp,0xfffffff0
<Factionwars> Yes and what do you think is odd about that (in your mind)
<rba_work> its a pretty high memory location?
<Factionwars> nothing odd about the +3 ?
<Factionwars> You didn't stepped there?
<Factionwars> Type in disas
<Factionwars> or disas main
<Factionwars> Don't you see any instructions before the current?
<rba_work> there are two. push ebp and mov ebp,esp

Code: [Select]
(gdb) run 10
Starting program: /home/rba/asm/lesson3 10
Dump of assembler code for function main:
   0x0804844c <+0>:    push   ebp
   0x0804844d <+1>:    mov    ebp,esp
=> 0x0804844f <+3>:    and    esp,0xfffffff0
...

Quote
<Factionwars> yay
<Factionwars> :D
<Factionwars> Those are +0 and +1
<rba_work> yes
<Factionwars> Location of main +0
<Factionwars> that is what the + means
<Factionwars> Well
<Factionwars> To get to the point
<Factionwars> GDB skipped those 2 instructions because they are the most basic unix function prologue
<Factionwars> The prologue is there to set up everything for the function to work correctly in it's own space.
<Factionwars> The prologue is in +0 - +6 in this function
<Factionwars> What happens is a pretty rough concept to get at first. But it saves the EBP, which is the base pointer of the stack on the stack. Then is moves esp (the current top of the stack) into ebp ( the bottom of the stack ) Thus resulting in ?
<Factionwars> What do you think?
<Factionwars> Maybe try to visualize if you can
<rba_work> give me a minute.. lol :P
<Factionwars> Just say if you don't know:P
<Factionwars> You don't have to think about it forever
<Factionwars> rba_work, i understand that you have a slow monday but you can throw the ball back at me already :P
<rba_work> I don't get it.. first I push the empty ebp on the stack. Afterwards I copy the location esp is pointing to ebp. this should be the location of the top of the stack, right?
<Factionwars> Yes
<Factionwars> Mhm
<rba_work> good.. is the and the logical and operation?
<Factionwars> No don't go on yet:P
<rba_work> ok
<Factionwars> You don't know what the begin means :P
<Factionwars> See it as a paper folded staircase.
<Factionwars> Those shitty things kids create just to waste paper and annoy teachers
<Factionwars> Imagine yourself keeping it up
<Factionwars> And move the beginning to the upper place
<Factionwars> This will result in ?
<Factionwars> You having a new?
<rba_work> stair?
<Factionwars> Yes so doing that on a stack will give you a new stack :D
<Factionwars> But it's called a stack frame
<Factionwars> sadly
<rba_work> that means the main function gets a new stack frame?
<Factionwars> Yes
<rba_work> for its local variables and stuff
<Factionwars> Correct :)

0x04 sub esp, 0x20

Quote
<Factionwars> What then happens is the biggest brainfuck you will have to get around when using a stack
<Factionwars> 0x08048436 <+6>:    sub    esp,0x20
<Factionwars> rba_work,
<Factionwars> The stack grows downward
<Factionwars> DEAL WITH IT
<Factionwars> lol
<Factionwars> In linux the stack grows downwards by default
<rba_work> from high to low memory locations, right?
<Factionwars> correct





Quote
<Factionwars> To give you a little idea of how that would look
<Factionwars> The subtract esp by 0x20 is to make space for variables
<Factionwars> This is because the GNU compiler doesn't really use POP and PUSH for optimization but uses offsets from esp
<Factionwars> We can see this in the next cmp instruction

0x05 cmp DWORD PTR [ebp+0x8],0x1

Quote
<rba_work> DWORD PTR is a 4byte pointer?
<Factionwars> Yes :)
<Factionwars> the funny thing is
<Factionwars> Something you really need to focus on now to remember it and let is make sense
<Factionwars> [ebp+0x8]
<Factionwars> This goes against everything i just told. Do you know whY?
<rba_work> tbh... no :( it compares the location saved in ebp+0x8 with 0x1.. I don't see how that makes sense :(
<Factionwars> I can totally understand that :D
<Factionwars> I woulnd't get it either xD
<Factionwars> Well the stack grows from high to low memory
<Factionwars> And ebp is the base of the stack
<Factionwars> Thus ebp+0x8 being out of the current...?
<rba_work> if ebp is the beginning of my stack frame it should hold the highest available address in the stack frame. adding dec 8 to it would be outside the stack frame. It should be -8 as it grows from high to low memory locations?
<Factionwars> Correct,
<Factionwars> And this is because the calling convention used on linux and specifically in this architechture, elf file and whatnot. Says that you should pass the arguments by stack
<Factionwars> So when you call a function and you want to give arguments to that function you push them on the stack and call the function. Then the function creates his own stack frame resulting in the arguments being at ebp+0x08
<Factionwars> Being before the stack frame
<Factionwars> Does this make any sense?
<Factionwars> Trust me when you get the hang of thinking at this level everything will go smoothly in the rest of your life
<rba_work> the arguments for my function are stored in a different stack frame?
<Factionwars> Well, yes
<Factionwars> Just before the current
<Factionwars> And as you see you can very easily adress it
<Factionwars> In fact that cmp is the same as if(argc < 2)
<rba_work> why compare it with 0x01.. shouldn't it be 0x02?
<Factionwars> Well
<Factionwars> That is because a cmp always comes with a jump
<Factionwars> Or a different action
<Factionwars> \
<Factionwars> But as you can see it is followed by a jump
<Factionwars> "jg"
<Factionwars> Jump if greater
<Factionwars> And if it's greater than 1 it jumps past the printf
<Factionwars> It's inverted. Compilers do such thing all the time to optimize everything
<Factionwars> Ah well
<Factionwars> Where i wanted to go was
<Factionwars> Why is the arguments at 0x08
<Factionwars> let's first find the argument
<Factionwars> Do you remember your argument?
<Factionwars> You can re-run the program with "r ARGUMENT"

Code: [Select]
(gdb) r 10
The program being debugged has been started already.
Start it from the beginning? (y or n) y

0x06 gdbs examine command

Quote
<Factionwars> Allright
<Factionwars> Lets inspect the location at ebp+0x8
<Factionwars> Do that
<Factionwars> Great try
<Factionwars> But you have no such clue
<Factionwars> THe fuck you doing
<rba_work>  trying to figure out how that x command works.. lol
<Factionwars> Dude
<Factionwars> Ask me
<Factionwars> I am waiting for you
<Factionwars> :P
<Factionwars> ASK ME XD
<rba_work> I have seen it a couple of times in the book.. lol. Thought I would be able to do it.
<Factionwars> Not without a little trick
<rba_work> its x/10dw.. but I don't understand the output.. can't see my 10 there
<Factionwars> No it's not
<Factionwars> Comon just ask me
<rba_work> how do I do it?
<Factionwars> First, to remember things we use (as said previously) namings. Words, phrases.
<Factionwars> EXAMINE ONE HEX BYTE FROM EBP+0x8
<Factionwars> Say it in your head
<Factionwars> Now say the exact same while reading x/1xb $ebp+0x8
<Factionwars> much easier ?
<rba_work> it actually makes sense that way :) Thats nice. I guess I can remember that :)

Code: [Select]
(gdb) x/1xb $ebp+0x8
0xbffffcc0:    0x02
0x02 > 0x01 :P

Quote
<Factionwars> Allright
<Factionwars> so
<Factionwars> examine number datatype length
<Factionwars> So you can do x/ two hex words from esp
<Factionwars> :)

Code: [Select]
(gdb) x/2hw $esp
0xbffffcb8:    0xbffffd38    0xb7e8de46

Quote
<Factionwars> Or you can do x/ one character byte from esp
<Factionwars> x/1cb esp

Code: [Select]
(gdb) x/1cb $esp
0xbffffcb8:    56 '8'

Quote
<Factionwars> you can also do x/s $esp
<Factionwars> examine string:P

Code: [Select]
(gdb) x/s $esp
0xbffffcb8:     "8\375\377\277F\336\350\267\002

Quote
<Factionwars> And
<Factionwars> try out x/i $eip
<Factionwars> Examine instruction at the location of $eip

Code: [Select]
(gdb) x/i $eip
=> 0x804844f <main+3>:    and    esp,0xfffffff0

Quote
<Factionwars> the print/x function prints the actual value of the register
<Factionwars> x/ dereferences it
<Factionwars> Look at this
<Factionwars> (gdb) print/x $eip
<Factionwars> (gdb) x/i 0x8048433
<Factionwars> What means that?

Code: [Select]
(gdb) print/x $eip
$1 = 0x804844f
(gdb) x/i 0x804844f
=> 0x804844f <main+3>:    and    esp,0xfffffff0

Quote
<Factionwars> It means that eip holds an .. to ..
<Factionwars> It's a mask operation
<Factionwars> but you don't have to worry about that for now
<Factionwars> Just some inverting of bits
<Factionwars> rba_work,
<rba_work> yes :)
<Factionwars> haven't filled in my sentence
<Factionwars> Or are you enjoying your own experiments? :P
<Factionwars> You are allowed to
<rba_work> yes :) I printed some registers :) It means that eip holds a pointer to the main functions stack frame?
<rba_work> no.. lol. thats doesn't make sense
<Factionwars> ip means ?
<rba_work> instruction pointer
<Factionwars> So eip holds the value of the current?
<Factionwars> the pointer to the current
<rba_work> memory location.. the next instruction that gets executed
<Factionwars> :)
<Factionwars> Now do "ni until you reach leave
<Factionwars> the leave instruction
<Factionwars> if you get the type return to continue all the time
<Factionwars> define hook-stop * enter* disas $eip, +30 *enter* end *enter*

Code: [Select]
(gdb) define hook-stop
Type commands for definition of "hook-stop".
End with a line saying just "end".
>disassemble $eip, +30
>end
(gdb) ni
Dump of assembler code from 0x8048452 to 0x8048470:
=> 0x08048452 <main+6>:    sub    esp,0x20
   0x08048455 <main+9>:    mov    DWORD PTR [esp+0x1c],0x96
   0x0804845d <main+17>:    cmp    DWORD PTR [ebp+0x8],0x1
   0x08048461 <main+21>:    jg     0x804846f <main+35>
   0x08048463 <main+23>:    mov    DWORD PTR [esp],0x8048540
   0x0804846a <main+30>:    call   0x8048320 <printf@plt>
   0x0804846f <main+35>:    mov    eax,DWORD PTR [ebp+0xc]
End of assembler dump.
0x08048452 in main ()
(gdb) ni
Dump of assembler code from 0x8048455 to 0x8048473:
=> 0x08048455 <main+9>:    mov    DWORD PTR [esp+0x1c],0x96
   0x0804845d <main+17>:    cmp    DWORD PTR [ebp+0x8],0x1
   0x08048461 <main+21>:    jg     0x804846f <main+35>
   0x08048463 <main+23>:    mov    DWORD PTR [esp],0x8048540
   0x0804846a <main+30>:    call   0x8048320 <printf@plt>
   0x0804846f <main+35>:    mov    eax,DWORD PTR [ebp+0xc]
   0x08048472 <main+38>:    add    eax,0x4
End of assembler dump.
0x08048455 in main ()
...
(gdb) ni
Dump of assembler code from 0x80484a8 to 0x80484c6:
=> 0x080484a8 <main+92>:    leave 
   0x080484a9 <main+93>:    ret   
   0x080484aa:    nop
   0x080484ab:    nop
   0x080484ac:    nop
   0x080484ad:    nop
   0x080484ae:    nop
   0x080484af:    nop
   0x080484b0 <__libc_csu_fini+0>:    push   ebp
   0x080484b1 <__libc_csu_fini+1>:    mov    ebp,esp
   0x080484b3 <__libc_csu_fini+3>:    pop    ebp
   0x080484b4 <__libc_csu_fini+4>:    ret   
   0x080484b5:    lea    esi,[esi+eiz*1+0x0]
   0x080484b9:    lea    edi,[edi+eiz*1+0x0]
   0x080484c0 <__libc_csu_init+0>:    push   ebp
   0x080484c1 <__libc_csu_init+1>:    mov    ebp,esp
   0x080484c3 <__libc_csu_init+3>:    push   edi
   0x080484c4 <__libc_csu_init+4>:    push   esi
   0x080484c5 <__libc_csu_init+5>:    push   ebx
End of assembler dump.
0x080484a8 in main ()

0x07 the leave instruction

Quote
<rba_work> ok.. the next step would be leave
<Factionwars> Allright
<Factionwars> What leave does it takes the adress before ebp
<Factionwars> Wich is the previous base pointer as you remember
<Factionwars> And puts it in ebp
<Factionwars> Thus restoring the old base pointer
<Factionwars> Can you understand that?
<Factionwars> You can look at it

Code: [Select]
(gdb) x/1xw $ebp
0xbffffcb8:    0xbffffd38

Quote
<Factionwars> That could be it
<Factionwars> Now step over leave and print ebp
<Factionwars> See if you where right (and i
<Factionwars> uh
<Factionwars> no
<Factionwars> x/1xw $ebp
<Factionwars> Try it
<Factionwars> could be that value
<Factionwars> :P

Code: [Select]
(gdb) ni
Dump of assembler code from 0x80484a9 to 0x80484c7:
=> 0x080484a9 <main+93>:    ret   
   0x080484aa:    nop
   0x080484ab:    nop
   0x080484ac:    nop
   0x080484ad:    nop
   0x080484ae:    nop
   0x080484af:    nop
   0x080484b0 <__libc_csu_fini+0>:    push   ebp
   0x080484b1 <__libc_csu_fini+1>:    mov    ebp,esp
   0x080484b3 <__libc_csu_fini+3>:    pop    ebp
   0x080484b4 <__libc_csu_fini+4>:    ret   
   0x080484b5:    lea    esi,[esi+eiz*1+0x0]
   0x080484b9:    lea    edi,[edi+eiz*1+0x0]
   0x080484c0 <__libc_csu_init+0>:    push   ebp
   0x080484c1 <__libc_csu_init+1>:    mov    ebp,esp
   0x080484c3 <__libc_csu_init+3>:    push   edi
   0x080484c4 <__libc_csu_init+4>:    push   esi
   0x080484c5 <__libc_csu_init+5>:    push   ebx
   0x080484c6 <__libc_csu_init+6>:    call   0x804851a <__i686.get_pc_thunk.bx>
End of assembler dump.
---Type <return> to continue, or q <return> to quit---
0x080484a9 in main ()
(gdb) x/1xw $ebp
0xbffffd38:    0x00000000

# - Lesson 4 jump, call and functions

0x01 The call instruction

Quote
<Factionwars> Okay as first
<Factionwars> The call instruction
<Factionwars> Do you already know what it does? (without looking up)
<rba_work> call   0x8048350 <atoi@plt> this? It looks like a call to the c function atoi
<rba_work> but I have no clue what @plt means
<Factionwars> Yes but what exactly do you think is a "call" on this level?
<Factionwars> A jump is "change EIP to that location"
<Factionwars> So why would we need an call?
<Factionwars> No clue? :)
<rba_work> not really :( because it is part of a c library?
<Factionwars> Yay
<Factionwars> I like explaining
<rba_work> Yes.. please explain it to me :)
<Factionwars> A call instruction is really made for functions at the lowest level. It is the same as jmp but with 1 difference, and that is that it pushes a return adress to the stack.
<Factionwars> This return adress is the next instruction after the call instruction.
<Factionwars> And then we have the "ret" instruction, it's basically a return  instruction wich is the exact opposite of the call instruction. It pops the return adress off the stack and goes there.
<Factionwars> Is this clear to you?
<Factionwars> It some pretty easy logic
<rba_work> this means the call instruction tells eip on which memory location it should execute the next instruction?
<Factionwars> But the jmp instruction also does this
<Factionwars> What is the difference?
<rba_work> I think jump belongs to a conditional statement like if and call just gets executed?
<Factionwars> Are you awake?
<Factionwars> Read my first sentence please :D
<rba_work> ah :) it pushes a return address to the stack.
<Factionwars> :)
<rba_work> so eip knows where to execute the next statement after the call is done?
<rba_work> call   0x8048350 <atoi@plt> is this 0x8048350´the return address?
<Factionwars> Well
<Factionwars> I can explain the call and ret logic in instructions
<Factionwars> call:
<Factionwars> push eip
<Factionwars> jmp function
<Factionwars> ret:
<Factionwars> pop eax
<Factionwars> jmp eax
<Factionwars> So the call instruction saves the return adress and the "ret" (return) instruction takes that (if the stack is restored to it's previous state so the return address is at the top) and jmps to that return adress
<Factionwars> And in order to not get a loop call pushes the next instruction on the stack
<Factionwars> Is that easy to understand?
<rba_work> not really easy but I think I got that.
<Factionwars> Allright, in order to fully understand it i want you to write it in asm
<Factionwars> We will write a full function without the stackframe hassle
<rba_work> ok.. One question. that pop eax means that the information which is on top of the stack gets writen into eax?
<Factionwars> jep :)
<rba_work> written*
<Factionwars> And removed off the stack
<Factionwars> You see this function in loads of languages with the same meaning
<rba_work> yes.. Then I really understood the example :)
<Factionwars> Even python has a array.pop :)
<rba_work> true :)
<Factionwars> So open up a piece of asm
<Factionwars> Same skeleton
<rba_work> ok.. I have that :)
<Factionwars> Well what do you want your function to do?
<rba_work> return the sum of two integers?
<Factionwars> print it ?
<rba_work> sure :)
<Factionwars> Allright
<Factionwars> Remove the _start
<Factionwars> keep the global _start
<Factionwars> You will write the _start after you have written your function
<Factionwars> So create a label for your function
<rba_work> ok.. I called it function :)
<Factionwars> Come on dude
<Factionwars> Call it something fance
<Factionwars> fancy
<rba_work> Ok :) as it should calculate the sum I call it sum :)
<Factionwars> great
<Factionwars> Okay let's assume you pass your variables through eax and ebx
<rba_work> I guess it is something like add eax, ebx.. but the define would not be db?
<Factionwars> Why do you need to define something ? :)
<Factionwars> http://en.wikibooks.org/wiki/X86_Assembly
<Factionwars> See if you can find the correct instruction
<rba_work> mhhh.. I guess I just need to initialize a var which holds the sum in the end?
<Factionwars> Why do you think that?
<rba_work> true.. I don't need that. when I do add eax, ebx eax will hold the sum, right?
<Factionwars> yes :)
<Factionwars> And eax is usually the return value of a function
<Factionwars> So that's easy
<Factionwars> and then return
<rba_work> ok.. I have no clue what I need to define in the data section :(
<Factionwars> Do you need to?
<rba_work> I don't think so. Do I?
<rba_work> lol
<Factionwars> Nope
<rba_work> So I just create a label without defining anything?
<Factionwars> Jep :)
<Factionwars> Things are not so hard as you think
<Factionwars> A label is just an adress
<Factionwars> Or an offset
<rba_work> do I need to define the label in the .data section in order to use it like this global _sum \n _sum: ?
<rba_work> no I guess. That would be a section and not a label, right? Need to get the right terms. lol
<Factionwars> You don't have a reason for it. And the .data section is used for specific variables.
<Factionwars> Not for function locations :P
<Factionwars> And there is also no reason of making it a global function right?
<Factionwars> You are calling the function in the same file
<rba_work> now that you say it.. right :)
<Factionwars> in the same section
<Factionwars> You have to think more low level, a call is a push and a jmp
<Factionwars> to an adress
<Factionwars> There is no such function
<Factionwars> That is a funciton
<Factionwars> It's that easy
<Factionwars> So in order to make a call work you only need a adrress of where to go
<Factionwars> There we will use nasm's labels because we don't want to hassle with adresses
<rba_work> That makes it a bit more clear.. but I still haven't got the big picture. By defining a label I have a name for a memory location. The return address gets pushed to the stack when I do a call function. would that be call label <function>? Lately I am really dull.. lol
<Factionwars> There is no such thing as <function>
<Factionwars> " By defining a label I have a name for a memory location. " < perfect
<Factionwars> Let's say it in different words.
<Factionwars> There is no such thing as a function at this level. You are the one to create the function logic.
<Factionwars> You are here to jump to a location, and when the instructions on that location are done return to the main logic. That is a function.
<Factionwars> And when writing asm you have to write the jmp to the adress and return to a adress.
<Factionwars> You can do it with jmp, call, ret whatever you like xD
<Factionwars> "Pushes the address of the next opcode onto the top of the stack, and jumps to the specified location. This is used mostly for subroutines."
<rba_work> ok.. so the label is the memory location where my function is located?
<Factionwars> Yes
<Factionwars> It's the same in C/C++, it's just a memory location :)
<rba_work> Now I got that.. I push the return address (which is the address of the first instruction I want to execute after the call to the stack and jump to the address where the instructions of my function are located. Afterwards I return which basically pops the return address from the stack and passes that to eip so eip knows where to go on?
<Factionwars> Yes :)
<Factionwars> only "the call to the stac" is weird
<rba_work> right.. should be call to the function not stack
<rba_work> I guess it will get more clear to me when we write the code :)
<Factionwars> Go ahead
<Factionwars> try to write some
<Factionwars> Just wriite
<rba_work> So I have my label which holds a memory location. Now I would need to write the code of the function into that location? how can I do that?
<rba_work> do I create a section for it and in the data section I would do sum: _func ?
<rba_work> I don't get it.. lol
<Factionwars> section .text  /../
<Factionwars> MyFunction:
<Factionwars> code
<Factionwars> _start:
<Factionwars> more code
<rba_work> ok.. I will try it :)
<rba_work> no matter what I do it always gives me a seg fault.. lol
<Factionwars> pastebin
<rba_work> its not much.. I guess the problem is that I call sum but it is not the location where _myfunc is at ???

Nothing to see here.. :P That RBA guy was pretty, pretty dull .. lol

0x02 The jump instruction

Quote
<Factionwars> Ohmygod
<Factionwars> omyfucking god rba_work
<Factionwars> Is your head empty?
<rba_work> seems like :(
<Factionwars> How many times did we talk about that you don't need to do ANYTHING ANYTHFUCKINGTHING with the data segment
<Factionwars> You told me 3 times :P
<Factionwars> THERE IS NO SUCH THING AS A FUNCTION
<Factionwars> THERE IS NOTHING TO DEFINE
<Factionwars> You are now jumping into the data segment
<Factionwars> Wich is not allowed
<Factionwars> Thus giving you a segfault
<Factionwars> Okay we are going to step down
<Factionwars> drop the whole call instruction
<Factionwars> It's to complicated for your braincells
<Factionwars> use a jmp
<Factionwars> and at the end of your function jmp back to a label after the previous jmp
<Factionwars> rba_work,
<Factionwars> rba_work,
<rba_work> still trying to figure that out...
<Factionwars> How far did you get?
<Factionwars> It's just jmping to a label
<Factionwars> there is NOTHING fancy happening
<Factionwars> Stop thinking like this is rocket science
<rba_work> still searching how to define labels that hold the addresses where I actually want to jump to
<Factionwars> jezus
<Factionwars> :P
<Factionwars> Why don't you fucking ask
<Factionwars> You are wasting your time
<Factionwars> You already defined a label _start
<Factionwars> ITS THAT EASY
<Factionwars> I am trying to say it all the fucking time
<Factionwars> You just have to listen to my words more carefully, and see that it's nothing fancy. Its just "MyLabel:"
<Factionwars> THATS IT
<Factionwars> no more declaratiopns
<Factionwars> NOTHING MORE
<Factionwars> WELL THAT IS FUCKING ANAL DILDO SCIENCE NOT?
<Factionwars> ANd throw away that fucking crap in your data segment
<Factionwars> rba_work, you are going to react right now:P
<rba_work> one sec.. I am trying it :)

Code: (asm) [Select]
section .text
        global _start         

Myfunc:
        add eax, ebx        ; calc eax + ebx
        jmp end                ; jump to the memory address where end is located

_start:
        mov eax, 0x05         ; set eax to dec 5
        mov ebx, 0x05         ; set ebx to dec 5
        jmp Myfunc

end:
        mov eax, 0x01         ; Linux syscall 1 (exit)
        xor ebx, ebx        ; exit return value 0
        int 0x80             ; Execute the syscall

0x03 the call instruction (again)

Quote
<rba_work> Ok.. I have that. Now that I know that _start: and stuff are also labels its quite easy. I am going to do it with call now :)
<Factionwars> FINALLY
<Factionwars> :P
<rba_work> ok.. I am still to stupid to get it working. Maybe its going better after the lunch break :)
<Factionwars> NO
<Factionwars> you lazy fuck
<Factionwars> stay here
<Factionwars> until it works
<Factionwars> pastebin now
<rba_work> it does not work and you will get angry if you see what I did do far :)
<Factionwars> No
<Factionwars> You are going to pastebin it
<Factionwars> You proceeded because i cursed on you
<Factionwars> :D
<rba_work>I am sure I am missing to tell the program where it should return to.. I need to pop something I guess.
<rba_work> give me a sec to go through the irc log.. maybe I can figure it out.. I am sure you already told me
<Factionwars> You are doing good
<Factionwars> But you don' get the return logic :)
<Factionwars> What should return
<Factionwars> The main logic or the function you call?
<rba_work> the function I call should return. I already tried to place the ret in the function.. but that doesn't work too
<Factionwars> Well do that first :)
<Factionwars> And it segfaults because there is no exit call
<rba_work> damn.. you are right.. lol. That works
<Factionwars> Congrats, the one who keeps trying succeeds :)

Code: (asm) [Select]
section .text
        global _start

Myfunc:
        add eax, ebx        ; calc eax + ebx
        ret                 ; return to the main logic
_start:
        mov eax, 0x05         ; set eax to dec 5
        mov ebx, 0x05         ; set ebx to dec 5
        call Myfunc         ; jump to Myfunc and push the return address to the stack
        mov eax, 0x01         ; Linux syscall 1 (exit)
        xor ebx, ebx         ; exit return value 0
        int 0x80             ; Execute the syscall

0x04 Output the result

Quote
[15:33:06] <rba_work> Factionwars: can you tell me why I only get a empty line ?

Code: (asm) [Select]
section .text
        global _start

Myfunc:
        add eax, ebx            ; calc the sum from eax and ebx
        ret
_start:
        mov eax, 0x05           ; Give eax the value 5
        mov ebx, 0x05           ; Give ebx the value 5
        call Myfunc             ; call the function to calc the sum

        push eax                ; push the result to the stack

        mov eax, 0x04           ; write syscall
        mov ebx, 0x01           ; write to stdout
        mov ecx, esp            ; pointer to the result of Myfunc
        mov edx, 0x02           ; result is 10 = len 2
        int 0x80                ; execute the write syscall

        mov eax, 0x01           ; exit syscall
        xor ebx, ebx            ; exit status 0
        int 0x80                ; execute the exit syscall

can you answer my question. Tbh its pretty obvious :P

0x05 Using external commands (printf)

Quote
<Factionwars> I feel an proud stumach feeling
<Factionwars> Almost correct :)
<Factionwars> The problem is that you are writing 10 to stdout. While 10 in the ascii table is "line feed" so that is not "10" or any other character. 
<Factionwars> Do you think it would be fun to try out printf?
<Factionwars> or you can use itoa
<Factionwars> rba_work,
<rba_work> is itoa a function I can use directly in nasm? or is it an external thing like printf?
<Factionwars> itoa doesn't exists by default nvm :P
<Factionwars> printf / sprintf is the way to go
<Factionwars> We can sprintf into a string or printf directly to the output
<Factionwars> Do you know how printf works?
<Factionwars> Pretty easy printf("The addition of 5 and 5 is: %d", int);
<rba_work> not really.. guess if I would have more c experience I would know that.,. lol. Damn python teaches you nothing.. lol
<Factionwars> Ah doesn't matter,
<Factionwars> hacking the art of explotation has a extensive format string guide
<Factionwars> But my example is pretty straight foward?
<Factionwars> Allright
<Factionwars> You can link your asm file with gcc
<rba_work> Ah.. yes.. I know that from python :)
<rba_work> the format string I mean
<Factionwars> yes
<Factionwars> When you compile it with gcc you can use libc functions
<Factionwars> The only thing you gotta do is change the _start to main
<Factionwars> not _main
<Factionwars> main
<Factionwars> and global main
<Factionwars> So gcc can find the main function
<Factionwars> [factionwars@Chronos c-research]$ vim printf.asm
<Factionwars> [factionwars@Chronos c-research]$ nasm printf.asm -o printf.o -felf32
<Factionwars> [factionwars@Chronos c-research]$ gcc -m32 printf.o -o printf
<Factionwars> [factionwars@Chronos c-research]$ ./printf
<Factionwars> Works very easily
<Factionwars> Just after the global main say extern printf. This is because gcc will then look elsewhere for printf, then you can do "call printf"
<rba_work> ok.. I understand that so far. But how do I pass what I want to print?
<Factionwars> Well, that is part of the calling convention. In libc that is by stack.
<Factionwars> And you will have to push the arguments in reverse.
<Factionwars> Because ofcourse the last item will be read first :)
<rba_work> so when I call printf it automatically passes what I pushed to the stack before?
<Factionwars> Not exactly, printf reads it from the stack
<Factionwars> Do you remember the arguments being ebp+
<Factionwars> So before the current stack frame :)
<Factionwars> That is where you push things
<Factionwars> So if you do a man 3 printf
<Factionwars> You will see that it requires a const char *format and then the parameters
<Factionwars> So define your strign in the data segment
<Factionwars> the format string
<Factionwars> with the %d
<Factionwars> And some gay text
<Factionwars> So the parameters are?
<Factionwars> rba_work,
<rba_work> sorry.. these damn users always want something from me when I don't have time for them.. lol
<Factionwars> xD
<rba_work> a pointer to the format? int printf(const char *format, ...);
<rba_work> that would be my label I defined in the data secion?
<Factionwars> formatstring or something
<rba_work> so I would need to push the register that holds the value I want to print and then my label?
<Factionwars> rba_work, that will do yes
<rba_work> I'll try that :)

That does not work. Do you know why?

Code: (asm) [Select]
section .data
        output: db "The sum of 5 and 5 is: %d"

section .text
        global main
        extern printf

Myfunc:
        add eax, ebx            ; calc the sum from eax and ebx
        ret
main:
        mov eax, 0x05           ; Give eax the value 5
        mov ebx, 0x05           ; Give ebx the value 5
        call Myfunc             ; call the function to calc the sum

        push eax                ; push the result to the stack
        push output             ; push the label to the stack

        call printf

        mov eax, 0x01           ; exit syscall
        xor ebx, ebx            ; exit status 0
        int 0x80                ; execute the exit syscall

Quote
<rba_work> Factionwars: that does not work. Am I missing something?
<Factionwars> rba_work, do "ltrace ./executable" in bash
<Factionwars> and gimme output
<Factionwars> Ehh
<Factionwars> You need to make it a valid string
<Factionwars> "gayy", 0x00
<rba_work> I see.. the null byte
<Factionwars> :)
<rba_work> damn.. lol
<Factionwars> And also throw in a newline
<Factionwars> %d\n
<Factionwars> rba_work, ?
<rba_work> it still prints nothing. :( ltrace says something about unfinished?
<rba_work> __libc_start_main(0x8048413, 1, 0xbfcaaad4, 0x8048440, 0x80484b0 <unfinished ...>
<rba_work> printf("The sum of 5 and 5 is: %d", 10)          = 25
<rba_work> +++ exited (status 0) +++
<Factionwars> PUT IN THE NEW LINE MY BUDDY
<Factionwars> THE PRINTF IS BEAUTIFULL
<Factionwars> BUT NOW WITHOUT A NEWLINE
<Factionwars> WON'T FLUSH SHIT
<Factionwars> NOT*
<rba_work> printf("The sum of 5 and 5 is: %d\\n", 10)       = 27
<Factionwars> NO
<Factionwars> \n
<Factionwars> not \\n
<rba_work> I only put one in... seems like the compiler wants to escape it???
<Factionwars> Okay
<Factionwars> And it does not give output when you run it without ltrace now?
<rba_work> yes
<Factionwars> no?
<rba_work> there is no output
<Factionwars> gimme yer code
<Factionwars> because you are trolling
<rba_work> I am not.. I would never do that.
<Factionwars> rba_work,
<Factionwars> remove the \n
<Factionwars> And replace it with the real ascii version
<Factionwars> ", 0x0A, 0x00
<Factionwars> 0x0a == newline
<rba_work> ok.. I'll try it
<rba_work> awesome :) it works :) many thanks :P

Code: (asm) [Select]
section .data
        output: db "The sum of 5 and 5 is: %d", 0x0a, 0x00

section .text
        global main
        extern printf

Myfunc:
        add eax, ebx            ; calc the sum from eax and ebx
        ret
main:
        mov eax, 0x05           ; Give eax the value 5
        mov ebx, 0x05           ; Give ebx the value 5
        call Myfunc             ; call the function to calc the sum

        push eax                ; push the result to the stack
        push output             ; push the label to the stack

        call printf

        mov eax, 0x01           ; exit syscall
        xor ebx, ebx            ; exit status 0
        int 0x80                ; execute the exit syscall

# - Lesson 5 command line arguments

0x01 - Where are the command line arguments located

Quote
<Factionwars> Where did you left of?
<rba_work> I tried to get the command line arguments :)
<Factionwars> And ?
<Factionwars> How did you end up
<rba_work> Can I tell you what I found out and you tell me if its correct?
<Factionwars> Yessir i can help you
<Factionwars> Can't give you an intense lesson
<rba_work> ok.. basically the command line arguments I pass to the script are available on the stack when the program starts. On the stack frame that belongs to my main: or _start
<rba_work> on the top of the stack (at the highest address) is the Argument count
<rba_work> then the Address of the program path and then the first argument and so on
<rba_work> so I did a pop ebx (to store the Argument count)
<rba_work> pop ecx to store the address of the program path

le Stack:


Quote
<Factionwars> yhea
<Factionwars> Not going to work :P
<Factionwars> right?
<Factionwars> You are close though
<Factionwars> You should use a character like AAAAAA for the argument and then inspect with GDB where it ends up
<Factionwars> This by analyzing the stack
<rba_work> printf prints something but its not the value I past.. thats a good idea :)
<Factionwars> Just break main and see where the arguments are on the stack
<Factionwars> First
<Factionwars> Gimme the command for examining 10 hexadecimal words from the stack
<Factionwars> A word in GDB is 32bits/
<rba_work> x/10xw ?
<Factionwars> Yes and from where?
<rba_work> but how do I look at the stack
<rba_work> esp?
<Factionwars> Great :D
<Factionwars> You are doing great
<Factionwars> And if you analyze it and think very deep you might know why the arguments are not where you want
<Factionwars> want them to be
<rba_work> and there would be my other question.. lol. I searched and found examples where they get the value by doing mov eax, [esp+8] for the first Argument. why is it +8 and not -8. I know that we talked about it but I guess I did not really understand.. lol
<Factionwars> You kinda did understand by then :)
<Factionwars> Well it should be ebp
<Factionwars> But i want you to analyze a bit
<Factionwars> googling is not going to help you any further
<Factionwars> Or me saying the answerd
<Factionwars> answers
<rba_work> I will do it.. just need to write it again.. forgot to push my last stuff.. lol
<Factionwars> You don't need the printf
<Factionwars> You can rewrite
<rba_work> should I do it with the write syscall?
<Factionwars> Sure

Code: (asm) [Select]
section .text
        global _start

_start:
        pop ecx                    ; get the number of arguments
        pop ecx                    ; get the program name
        pop ecx                    ; get the first argument

        mov eax, 0x04           ; write syscall
        mov ebx, 0x01           ; write to stdout
                                ; ecx already holds the first command line argument
        mov edx, 0x02           ; print the first two bytes
        int 0x80                ; execute the write syscall

        mov eax, 0x01           ; exit syscall
        xor ebx, ebx            ; exit status 0
        int 0x80                ; execute the exit syscall


0x02 Examine the Stack

Quote
<rba_work> ok.. when I use the write syscall it prints the correct value. printf always printed the address where my value was at. Was not so obvious cause I printed it in dec
<rba_work> I will look at the stack now with gdb :)
<rba_work> hmm.. I set a breakpoint at _start and run it. If I want to use the examine command I always get the message
<rba_work> (gdb) x/10xw esp
<rba_work> No symbol table is loaded.  Use the "file" command.
<Factionwars> does write give you AAAA
<rba_work> but disas shows something
<Factionwars> $esp
<Factionwars> not esp,
<rba_work> right.. damn. When will this finally get into my brain lol
<rba_work> it basically prints it.. but as I need to supply a length for the output its difficult
<Factionwars> yah
<Factionwars> where is it on the stack now?
<Factionwars> No
<Factionwars> different question
<Factionwars> Why would this in c/c++ be in a different location?
<Factionwars> That relates to the ebp + 8 thingie
<rba_work> ebp points to the top of the stack too, right?
<Factionwars> Your kidding me?
<Factionwars> Don't google
<Factionwars> dont go anywhere else
<Factionwars> THINK
<rba_work> its the base pointer
<Factionwars> CRUNCH YOUR FUCKING BRAIN
<Factionwars> so where does it point to
<rba_work> hmm.. esp was the stack pointer which points to the top of the stack.. ebp had something to do with the stack frame, right?
<rba_work> I can't remember it :(
<Factionwars> the fuck does the name suggests
<rba_work> I know we had it when we disassembled the c code. There it was used to allocate space.. thats what I can recall
<Factionwars> BASE POINTER
<Factionwars> BASE
<Factionwars> STACK TOP
<Factionwars> ESP TOP
<Factionwars> EBP BASE POINTER
<Factionwars> see the logic? :D
<Factionwars> corona again
<Factionwars> Maybe cures the headache
<rba_work> I guess your headache will get worst when we go on :)
<Factionwars> No this is part of my method
<Factionwars> Lesson 102
<Factionwars> STACK
<Factionwars> ESP points to the top of the stack
<Factionwars> EBP points to the base/bottom of the stack
<Factionwars> rba_work,
<Factionwars> what are you doing
<rba_work> trying to get my boss out of my office :)
<rba_work> ok.. guess I can remember it this way :)
<rba_work> so why would this in c/c++ be in a different location was the question.
<Factionwars> Yes
<rba_work> has it something to do with the function prologue?
<Factionwars> Yes
<rba_work>    0x0804844c <+0>:    push   ebp
<rba_work>    0x0804844d <+1>:    mov    ebp,esp
<rba_work> => 0x0804844f <+3>:    and    esp,0xfffffff0
<rba_work>    0x08048452 <+6>:    sub    esp,0x20
<rba_work> this was the prologue
<Factionwars> The +6 is also prologue, but untill +1 is the original prologue.
<Factionwars> You only need to care for the original for now
<Factionwars> The sub at +6 is because GNU compilers don't use push and pop but rather use direct methods live mov eax, [esp+10]
<Factionwars> Don't ask me why, probably optimization
<rba_work> ebp does not point to the bottom of the stack anymore after this operation. it points to the top
<Factionwars> YEs
<Factionwars> go on
<rba_work> this is to prepare the stack frame for the main function?
<Factionwars> Yes, this is because functions use stack frames. These are kind of virtual stack frames.
<Factionwars> Virtual stacks
<Factionwars> To keep things sepperated
<Factionwars> And rba_work
<Factionwars> Last killer question
<Factionwars> You should not google
<Factionwars> I can teach it
<Factionwars> why ebp + 0x08
<Factionwars> When it is out of the current stack frame
<Factionwars> So it's not in between esp and ebp
<Factionwars> Why would you + on ebp
<Factionwars> When it's not in between esp and ebp
<rba_work> Because these arguments are not stored in the (lets call it) main stack frame?
<rba_work> main functions stack frame
<Factionwars> That is not the answer what i a looking for
<Factionwars> When i have var1 and var2
<Factionwars> var1 is 0 and var2 is 10
<Factionwars> I do var1+0x08 then it's still between var1 and var2 right ? :)
<Factionwars> Why does this not apply for the stack
<Factionwars> Don't google  :)
<Factionwars> You might read the lessons
<Factionwars> But you can also think very deeply :P
<Factionwars> Million dollar question if you answer it in 10 seconds
<Factionwars> Suck to be you mate
<Factionwars> You could have gotten 1 million
<rba_work> I would prefer to get the answer instead :) lol. The stack grows downwards
<Factionwars> Wasn't that hard right?
<rba_work> absolutely not.. lol.
<Factionwars> Can you understand it?
<rba_work> I guess I will paint a picture later :)
<Factionwars> VAR1  10, 9, 8, 7, 6, 5, 4, 3, 2, 1  VAR2,     VAR1 +0x08
<Factionwars> Doesn't result in the stack frame :)
<Factionwars> EBP 10, 9, 8, 7, 6, 5, 4, 3, 2, 1  ESP,     EBP +0x08
<Factionwars> Does that draw you a nice picture?
<Factionwars> I hope not of cocks
<Factionwars> But you are totally free to imagine that.
<Factionwars> I am not here to limit your sexuality
<Factionwars> Though in the end you will be a real man
<rba_work> lol :) yes this really helps :)
<Factionwars> It's just all those little details where you need to focuss on in order to truly understand things.
<Factionwars> When you rage over those things you will get frustrated in the end
<rba_work> guess without your help I would have given up already :)

Quote
<Factionwars> rba_work, :D
<rba_work> hi :) can you please give me a hint how I can follow a pointer in gdb :( I tried and tried yesterday.. but without any results. Give me a sec to open it up and show you what I mean
<Factionwars> Sure
<rba_work> ok.. basically I pop the first argument from the stack which is a pointer to the program name and save it in ebx. When I do Examine 1 hex word (cause the address should be 4 byte / 32 bits) I see the following:
<rba_work> (gdb) x/1xw $ebx
<rba_work> 0xb7e354d3 <__libc_start_main+243>:     0xe8240489
<rba_work> now I want to see what is at that address so I do the same just with the address
<rba_work> (gdb) x/1xw 0xe8240489
<rba_work> 0xe8240489:     Cannot access memory at address 0xe8240489
<rba_work> so its not a memory location?
<rba_work> but it should be as it is a pointer???
<Factionwars> What is the difference between x/ and print/x?
<Factionwars> rba_work,
<rba_work> print/x dereferences.. I still need to look up what that means :P
<Factionwars> WHAT DID I SAY
<Factionwars> YOU DON'T LOOK THINGS UP WHEN IN CLASS YOU BITCH ASS
<Factionwars> :P
<Factionwars> "Factionwars what exactly does dereferences mean" If you don't ask you are wasting lessons, really because if you don't ask for clarification how am i supposed to know you understand any? :)
<rba_work> can you explain to me what that really means?
<rba_work> I need to go for a couple of minutes to plug some cables :( I am back in 10 minutes.. thats the dark side of this job. lol
<Factionwars> okay
<Factionwars> Allright,
<Factionwars> Another name for a pointer is a reference. Because when you have a reference to something infact it points you to that object. When you have a reference to a shop and you drive there it points you to the shop. Well this explains the term dereferencing. When you dereference something you turn the pointer into the actual object.
<Factionwars> When i have a pointer "int * a"
<Factionwars> While a is a pointer, i dereference it with *a then it is not a pointer but a integer.
<Factionwars> print/x prints the value of something.
<Factionwars> x/1xw takes the pointer out of the object you give to it and looks at the value of that pointer. So x/ will only work if you give it a pointer to a pointer, where EBX holding a pointer is valid becaues it will first look at ebx, then at the pointer, then at the value of the pointer.
<rba_work> ok.. good explanation.. I think I understand that now. So basically if ebx holds a pointer.. print/x should print the value the pointer points to, right?
<Factionwars> The other way around
<Factionwars> print/x will give you the value of EBX
<rba_work> (gdb) print/x $ebx
<rba_work> $1 = 0xb7e354d3
<Factionwars> x/ will give you the value where EBX points to
<Factionwars> do print/x and compare the value with "info registers"
<rba_work> they are the same
<Factionwars> :)
<Factionwars> And x/ ?
<Factionwars> Compare x/1xw $ebx and print/x 0xb7e354d3
<Factionwars> owh no
<Factionwars> uh
<Factionwars> x/1x 0xb7e354d3
<rba_work> (gdb) x/1xw $ebx
<rba_work> 0xb7e354d3 <__libc_start_main+243>:     0xe8240489
<rba_work> (gdb) x/1x 0xb7e354d3
<rba_work> 0xb7e354d3 <__libc_start_main+243>:     0xe8240489
<rba_work> always the same
<Factionwars> yah
<rba_work> guess I don't get it :( ebx is a pointer to 0xb7e354d3 which holds 0xe8240489 ?
<Factionwars> ebx is a register. And you need to treat it differently in gdb
<Factionwars> meh
<Factionwars> morning
<rba_work> treat it differently?
<rba_work> hey.. I can do that to to dereference it x/1xw (*$ebx)


Quote
<rba_work> Factionwars: ? Mind giving me another hint? I still don't get it. No matter what I do I can't locate the values. I even stopped before the first argument gets popped and x esp but I always get the same.
<Factionwars> Why are you so certain you have the good values?
<Factionwars> Maybe you are fucking a return adress
<Factionwars> or some other crap
<Factionwars> How have you located it ?
<Factionwars> First find the number of arguments on the stack
<Factionwars> so give 1 1 1 1 1 as a argument. Then locate 0x05 on the stack by doing x/30xb $esp
<rba_work> Yes.. I have done that before. its at esp+4 and it is 0x06
<rba_work> its the only one of the three values I can find.. lol
<rba_work> or more values in that case
<Factionwars> Well
<Factionwars> If you read a byte from it and it is the argument size, then the next 4 bytes are the first char pointer
<Factionwars> Should i try it ?
<Factionwars> rba_work,


Code: [Select]
(gdb) x/50xb $esp
0xffffd8f0:    0x06    0x00    0x00    0x00    0x88    0xda    0xff    0xff
0xffffd8f8:    0xb7    0xda    0xff    0xff    0xb9    0xda    0xff    0xff
0xffffd900:    0xbb    0xda    0xff    0xff    0xbd    0xda    0xff    0xff
0xffffd908:    0xbf    0xda    0xff    0xff    0x00    0x00    0x00    0x00
0xffffd910:    0xc1    0xda    0xff    0xff    0xcc    0xda    0xff    0xff
0xffffd918:    0xdd    0xda    0xff    0xff    0xef    0xda    0xff    0xff
0xffffd920:    0x24    0xdb
(gdb) x/20xw $esp
0xffffd8f0:    0x00000006    0xffffda88    0xffffdab7    0xffffdab9
0xffffd900:    0xffffdabb    0xffffdabd    0xffffdabf    0x00000000
0xffffd910:    0xffffdac1    0xffffdacc    0xffffdadd    0xffffdaef
0xffffd920:    0xffffdb24    0xffffdb35    0xffffdb4c    0xffffdb5c
0xffffd930:    0xffffdb67    0xffffdb7f    0xffffdb91    0xffffdbc5
(gdb) x/20xw $esp
0xffffd8f0:    0x00000006    0xffffda88    0xffffdab7    0xffffdab9
0xffffd900:    0xffffdabb    0xffffdabd    0xffffdabf    0x00000000
0xffffd910:    0xffffdac1    0xffffdacc    0xffffdadd    0xffffdaef
0xffffd920:    0xffffdb24    0xffffdb35    0xffffdb4c    0xffffdb5c
0xffffd930:    0xffffdb67    0xffffdb7f    0xffffdb91    0xffffdbc5
(gdb) x/s 0xffffda88
0xffffda88:    "/home/factionwars/Programming/c-research/a.out"
(gdb) x/s 0xffffdab7
0xffffdab7:    "a"

Quote
<Factionwars> Works great in _start
<rba_work> wut.. wait.. how did you do that.. let me try to understand it.. sec
<Factionwars> break _start
<Factionwars> r a a a a a
<Factionwars> x/20xw $esp
<Factionwars> first is the number of arguments
<Factionwars> OH
<Factionwars> rba_work,
<Factionwars> rba_work,
<Factionwars> do you have some time
<Factionwars> I see a lesson in this

0x03 The Endians

Quote
<Factionwars> 0x06 0x00 0x00 0x00 0x88 0xda 0xff 0xff AND 0x00000006 0xffffda88 0xffffdab7 0xffffdab9 are different
<rba_work> sure :) I may get interrupted for 20 min. but we can do it :)
<Factionwars> Do you see it?
<Factionwars> But in real they are the same
<Factionwars> How is that possible?
<rba_work> yes.. they are in reverse order. but I have no clue why.. lol
<Factionwars> e
<Factionwars> n
<Factionwars> d
<Factionwars> i
<Factionwars> an
<Factionwars> :D
<Factionwars> Ever heard of endiannes?
<Factionwars> big-endian, small-endian
<rba_work> yes.. heard it during network stuff.. one of it is also called network byte order.. but I can't remember which one. should be small-endian
<Factionwars> Big-endian :)
<Factionwars> Well, different cpu architechtures use different endianness.
<rba_work> really.. 128 64 32 16 8 4 2 1 is big endian?
<Factionwars> Yes :)
<Factionwars> Well
<Factionwars> Endianness is about how the bytes are ordered
<rba_work> ah.. if the biggest value is at the end its big-ENDian :)
<Factionwars> Actually at the beginning
<Factionwars>  0xffffda88
<Factionwars> while it was stored like  0x88 0xda 0xff 0xff
<Factionwars> You don't need to fully get it, just always take this into consider and know that you will have to switch some bytes around
<Factionwars> And look at it on byte level
<Factionwars> Man that was a horrid lesson
<rba_work> :P that was a good one.. not to much to overload my brain.. lol
« Last Edit: October 30, 2013, 11:21:30 am by RedBullAddicted »
Deep into that darkness peering, long I stood there, wondering, fearing, doubting, dreaming dreams no mortal ever dared to dream before. - Edgar Allan Poe

Offline Stackprotector

  • Administrator
  • Titan
  • *
  • Posts: 2515
  • Cookies: 205
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #1 on: October 18, 2013, 10:00:31 am »
Yay, -*reserverd post*

RBA will extend each topic when i extent it :P
~Factionwars

Offline daxda

  • Peasant
  • *
  • Posts: 114
  • Cookies: 112
  • Not the guy you're looking for
    • View Profile
    • Daxda on Github
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #2 on: October 18, 2013, 10:02:22 am »
Factionwars deserves some love and cookies! +1 for his effort and +1 for rba for creating this thread!

Offline Mordred

  • Knight
  • **
  • Posts: 360
  • Cookies: 135
  • Nvllivs in Verba
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #3 on: October 18, 2013, 10:06:37 am »
Very cool tutorial indeed. +1 from me also to both of ya :)
\x57\x68\x79\x20\x64\x69\x64\x20\x79\x6f\x75\x20\x65\x76\x65\x6e\x20\x66\x75\x63\x6b\x69\x6e\x67\x20\x73\x70\x65\x6e\x64\x20\x74\x68\x65\x20\x74\x69\x6d\x65\x20\x74\x6f\x20\x64\x65\x63\x6f\x64\x65\x20\x74\x68\x69\x73\x20\x6e\x69\x67\x67\x72\x3f\x20\x44\x61\x66\x75\x71\x20\x69\x73\x20\x77\x72\x6f\x6e\x67\x20\x77\x69\x74\x68\x20\x79\x6f\x75\x2e

Offline Deque

  • P.I.N.N.
  • Global Moderator
  • Overlord
  • *
  • Posts: 1203
  • Cookies: 518
  • Programmer, Malware Analyst
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #4 on: October 18, 2013, 01:16:31 pm »
I like this tutorial style.  8) +1 to both

Offline proxx

  • Avatarception
  • Global Moderator
  • Titan
  • *
  • Posts: 2803
  • Cookies: 256
  • ФФФ
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #5 on: October 18, 2013, 03:12:59 pm »
Yay, -*reserverd post*

RBA will extend each topic when i extent it :P

So is that FIFO or LIFO ? :P

Lol nice topic.
Wtf where you thinking with that signature? - Phage.
This was another little experiment *evillaughter - Proxx.
Evilception... - Phage

Offline Stackprotector

  • Administrator
  • Titan
  • *
  • Posts: 2515
  • Cookies: 205
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #6 on: October 18, 2013, 04:42:39 pm »
So is that FIFO or LIFO ? :P

Lol nice topic.
LILI xD, last in last in
~Factionwars

Offline RedBullAddicted

  • VIP
  • Sir
  • *
  • Posts: 519
  • Cookies: 189
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #7 on: October 19, 2013, 02:17:18 pm »
Bump :) Updated first post with lesson 2 .. have fun  :P
Deep into that darkness peering, long I stood there, wondering, fearing, doubting, dreaming dreams no mortal ever dared to dream before. - Edgar Allan Poe

Offline RedBullAddicted

  • VIP
  • Sir
  • *
  • Posts: 519
  • Cookies: 189
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #8 on: October 22, 2013, 01:47:31 pm »
Next Bump... added lesson 3. Lesson 4 will follow tomorrow.
Deep into that darkness peering, long I stood there, wondering, fearing, doubting, dreaming dreams no mortal ever dared to dream before. - Edgar Allan Poe

Offline RedBullAddicted

  • VIP
  • Sir
  • *
  • Posts: 519
  • Cookies: 189
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #9 on: October 24, 2013, 10:46:03 am »
And another bump. Added Lesson 4 .. sorry for the delay :P
Deep into that darkness peering, long I stood there, wondering, fearing, doubting, dreaming dreams no mortal ever dared to dream before. - Edgar Allan Poe

Offline RedBullAddicted

  • VIP
  • Sir
  • *
  • Posts: 519
  • Cookies: 189
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #10 on: October 30, 2013, 11:23:15 am »
Next Lesson added :P Its maybe a bit weird cause I took a long time to understand it. Many things do repeat but I think I finally got it. The next lessons will be more straight forward, I promise :P
Deep into that darkness peering, long I stood there, wondering, fearing, doubting, dreaming dreams no mortal ever dared to dream before. - Edgar Allan Poe

Offline kenjoe41

  • Symphorophiliac Programmer
  • Administrator
  • Baron
  • *
  • Posts: 990
  • Cookies: 224
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #11 on: January 11, 2014, 09:56:52 pm »
Just a quick question RBA, did you first go through the X86 Assembly book before all this?

Nice going with the lessons.
If you can't explain it to a 6 year old, you don't understand it yourself.
http://upload.alpha.evilzone.org/index.php?page=img&img=GwkGGneGR7Pl222zVGmNTjerkhkYNGtBuiYXkpyNv4ScOAWQu0-Y8[<NgGw/hsq]>EvbQrOrousk[/img]

Offline Stackprotector

  • Administrator
  • Titan
  • *
  • Posts: 2515
  • Cookies: 205
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #12 on: January 11, 2014, 10:14:23 pm »
Just a quick question RBA, did you first go through the X86 Assembly book before all this?

Nice going with the lessons.

Nope he did not, the most of this all is written towards learning the basics of kinda everything and that is required to understand asm. Assembly itself in it's most basic form is really easy but you will fail and find it really really hard if you do not go carefully over all the steps that are above and around the assembly level. If you'd had a extensive knowledge of C this would all be really easy, but there are little people who know the details. And it's the most important thing. And as a clue of this little talk: the details and the technical knowledge you will gather from learning this is 99% more useful than assembly itself
~Factionwars

Offline Mikkybow

  • Serf
  • *
  • Posts: 36
  • Cookies: 6
  • What Doesn't Kill Ya Makes You Stronger
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #13 on: January 12, 2014, 06:32:57 am »
Wow this is Awesome!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!. Great tutorial, so beautiful, +1 cookie for both of ya. :)
Complex. It must be stated that the
person that'll know my complexity
be a true genius.

Offline chiboy

  • Serf
  • *
  • Posts: 21
  • Cookies: 2
  • RESPECT is RECIPROCAL
    • View Profile
Re: Factionwars teaches ASM (x86 Linux Netwide Assembler)
« Reply #14 on: January 12, 2014, 06:39:10 am »
Ooooh man, Factionwars you rocks, you are a genius. Love you man +1 cookie.
Evilzone Is My Home