Dia 05
Removiendo símbolos del ejecutable
strip
: strip removes or modifies the symbol table attached to the output of the assembler and link editor. This is useful to save space after a program has been debugged and to limit dynamically bound symbols.
Part of a symbol table from a executable:
Symbol table '.symtab' contains 74 entries:
....
62: 0804b038 0 NOTYPE GLOBAL DEFAULT 25 _end
63: 080485fd 200 FUNC GLOBAL DEFAULT 13 dolor
64: 08048450 0 FUNC GLOBAL DEFAULT 13 _start
65: 080490b8 4 OBJECT GLOBAL DEFAULT 15 _fp_hw
66: 0804b034 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
67: 080486c5 2400 FUNC GLOBAL DEFAULT 13 main
68: 0804854d 176 FUNC GLOBAL DEFAULT 13 placer
69: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
70: 00000000 0 FUNC GLOBAL DEFAULT UND __isoc99_scanf@@GLIBC_2.7
71: 0804b034 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
72: 00000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
73: 0804839c 0 FUNC GLOBAL DEFAULT 11 _init
After stripping the executable, there is no symbol table. Disassemblers won't label the beggining of main or other local functions :-(
, however.... you may still find the beggining of main, just look for
__libc_start_main
The __libc_start_main()
` function performs any necessary initialization of the execution environment, calls the main function with appropriate arguments, and handles the return from main().
08048450 <.text>:
8048450: 31 ed xor %ebp,%ebp
8048452: 5e pop %esi
8048453: 89 e1 mov %esp,%ecx
. . . . .
8048467: 68 c5 86 04 08 push $0x80486c5
804846c: e8 af ff ff ff call 8048420 <__libc_start_main@plt>
. . . .
Compilación para AMD64 (x86-64)
Los registros en AMD64.
Si comienza con R, tiene 64-bits. Apoya legacy mode en que solo utiliza la parte de 32-bits (se llama E)
Pase de parámetros x86-64 (al menos en gcc linux)
From http://www.agner.org/optimize/calling_conventions.pdf page 10.
Passing Once arguments are classified, the registers get assigned (in left-to-right order) for passing as follows:
-
If the class is INTEGER, the next available register of the sequence
%rdi
,%rsi
,%rdx
,%rcx
,%r8
and%r9
is used. -
If the class is SSE, the next available vector register is used, the registers are taken in the order from %xmm0 to %xmm7.
Ejemplo compilando en AMD64 para observar el orden de los parámetros
- Observe como el compilador asigna las versiones 32-bit ya que el parámetro no requiere 64-bits
void func1(int a, int b, int c, int d, int e) {
a = 0x1;
b = 0x2;
c = 0x3;
d = 0x4;
e = 0x5;
}
int main() {
func1(0x11,0x22,0x33,0x44,0x55);
return 0;
}
func1(int, int, int, int, int):
push %rbp
mov %rsp,%rbp
mov %edi,-0x4(%rbp) ; notice how the parameters
mov %esi,-0x8(%rbp) ; are copied onto the local
mov %edx,-0xc(%rbp) ; variables...
mov %ecx,-0x10(%rbp)
mov %r8d,-0x14(%rbp)
movl $0x1,-0x4(%rbp)
movl $0x2,-0x8(%rbp)
movl $0x3,-0xc(%rbp)
movl $0x4,-0x10(%rbp)
movl $0x5,-0x14(%rbp)
nop
pop %rbp
retq
main:
push %rbp
mov %rsp,%rbp
mov $0x55,%r8d ; notice how the various
mov $0x44,%ecx ; parameters are copied
mov $0x33,%edx ; onto certain registers
mov $0x22,%esi
mov $0x11,%edi
callq 4004d7 <func1(int, int, int, int, int)>
mov $0x0,%eax
pop %rbp
retq
nopl 0x0(%rax,%rax,1)
Patrones en assembly
Recorriendo un arreglo
// Given an array A, and its size,
// return the sum of its elements
int sum(int *A, int size) {
int i = 0;
int accum = 0;
for (i = 0; i < size; i++) {
accum = ctr + A[i];
}
return accum;
}
int main() {
int A[] = {0x11,0x22,0x33};
return sum(A,3);
}
sum:
8048374: push %ebp
8048375: mov %esp,%ebp
8048377: sub $0x10,%esp
804837a: movl $0x0,-0x8(%ebp) ; i = 0
8048381: movl $0x0,-0x4(%ebp) ; accum = 0
8048388: movl $0x0,-0x8(%ebp) ; i = 0
804838f: jmp 80483a3 <sum+0x2f>
8048391: mov -0x8(%ebp),%eax ; eax = i
8048394: shl $0x2,%eax' ; eax = eax * 4;
8048397: add 0x8(%ebp),%eax ; eax = eax + arg1
804839a: mov (%eax),%eax ; eax = *eax
804839c: add %eax,-0x4(%ebp) ; accum = accum + eax
804839f: addl $0x1,-0x8(%ebp) ; i++
80483a3: mov -0x8(%ebp),%eax ; eax = i
80483a6: cmp 0xc(%ebp),%eax ; eax < size ?
80483a9: jl 8048391 <sum+0x1d> ; jump if true
80483ab: mov -0x4(%ebp),%eax ; eax = acum, to return it
80483ae: leave
80483af: ret
main:
40048d: push %rbp
40048e: mov %rsp,%rbp
400491: sub $0x10,%rsp
400495: movl $0x11,-0x10(%rbp)
40049c: movl $0x22,-0xc(%rbp)
4004a3: movl $0x33,-0x8(%rbp)
4004aa: lea -0x10(%rbp),%rdi
4004ae: mov $0x3,%esi
4004b3: callq 400448 <sum>
4004b8: leaveq
4004b9: retq
Loop examples
push ebp
mov ebp, esp
mov esi, [ebp + 8]
mov ebx, 0
mov eax, 0
mov ecx, 0
Label01: mov ecx, [esi + ebx * 4]
add eax, ecx
inc ebx
cmp ebx, 100
jne Label01
mov esp, ebp
pop ebp
ret
Example taken from csaw2012reversing.exe:
00401030 /$ 55 PUSH EBP
00401031 |. 8BEC MOV EBP,ESP
00401033 |. 51 PUSH ECX
00401034 |. C745 FC 000000>MOV DWORD PTR SS:[EBP-4],0
0040103B |> 8B45 08 /MOV EAX,DWORD PTR SS:[EBP+8]; [EBP+8] is a param which is a pointer
0040103E |. 0FB608 |MOVZX ECX,BYTE PTR DS:[EAX] ; move BYTE to reg with 0 ext
00401041 |. 85C9 |TEST ECX,ECX ;
00401043 |. 74 24 |JE SHORT csaw2012.00401069 ; jump if byte is zero
00401045 |. 8B55 08 |MOV EDX,DWORD PTR SS:[EBP+8] ;Once again access the param
00401048 |. 0FB602 |MOVZX EAX,BYTE PTR DS:[EDX] ;Put a character to EAX
0040104B |. 35 FF000000 |XOR EAX,0FF ;Xor it with 0xFF
00401050 |. 8B4D 08 |MOV ECX,DWORD PTR SS:[EBP+8] ;Copy it back
00401053 |. 8801 |MOV BYTE PTR DS:[ECX],AL
00401055 |. 8B55 08 |MOV EDX,DWORD PTR SS:[EBP+8] ;Increment the param
00401058 |. 83C2 01 |ADD EDX,1
0040105B |. 8955 08 |MOV DWORD PTR SS:[EBP+8],EDX ;
0040105E |. 8B45 FC |MOV EAX,DWORD PTR SS:[EBP-4] ; Get a local var
00401061 |. 83C0 01 |ADD EAX,1 ; Increment
00401064 |. 8945 FC |MOV DWORD PTR SS:[EBP-4],EAX ; And store back
00401067 |.^EB D2 \JMP SHORT csaw2012.0040103B
00401069 |> 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
0040106C |. 8BE5 MOV ESP,EBP
0040106E |. 5D POP EBP
0040106F \. C3 RETN
Branch example
push ebp
mov ebp, esp
mov eax, 0
mov ecx, [ebp + 8]
cmp ecx, 0
jne Label01
inc eax
jmp Label02
Label01: dec eax
Label02: mov ecx, [ebp + 12]
cmp ecx, 0
jne Label03
inc eax
Label03: mov esp, ebp
pop ebp
ret
A nice reference for x86: http://www.cs.virginia.edu/~evans/cs216/guides/x86.html